BRL-CAD
constraint.c
Go to the documentation of this file.
1 /* C O N S T R A I N T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2013-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 
24 #include "bu/cmd.h"
25 #include "ged.h"
26 
27 
28 HIDDEN int
29 constraint_set(void *datap, int argc, const char *argv[])
30 {
31  struct directory *dp;
33  struct bu_vls expression = BU_VLS_INIT_ZERO;
34  struct ged *gedp = (struct ged *)datap;
35 
36  if (!gedp || argc < 3 || !argv)
37  return BRLCAD_ERROR;
38 
40 
41  dp = db_lookup(gedp->ged_wdbp->dbip, argv[2], LOOKUP_QUIET);
42  if (!dp) {
43  /* TODO: need to create the object here */
44  return BRLCAD_ERROR;
45  }
46 
47  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
48  bu_vls_printf(gedp->ged_result_str, "Cannot get constraints for %s\n", dp->d_namep);
49  bu_avs_free(&avs);
50  return BRLCAD_ERROR;
51  }
52 
53  bu_vls_from_argv(&expression, argc-4, &argv[4]);
54  (void)bu_avs_add(&avs, argv[3], bu_vls_addr(&expression));
55  bu_vls_free(&expression);
56 
57  if (db5_update_attributes(dp, &avs, gedp->ged_wdbp->dbip)) {
58  bu_vls_printf(gedp->ged_result_str, "Failed to set constraints on %s\n", dp->d_namep);
59  bu_avs_free(&avs);
60  return GED_ERROR;
61  }
62 
63  bu_avs_free(&avs);
64 
65  return BRLCAD_OK;
66 }
67 
68 
69 HIDDEN int
70 constraint_get(void *datap, int argc, const char *argv[])
71 {
72  size_t i, obj;
73  struct directory *dp;
74  struct bu_attribute_value_set avs;
75  struct bu_attribute_value_pair *avpp;
76  int ret = BRLCAD_OK;
77 
78  struct ged *gedp = (struct ged *)datap;
79 
80  if (!gedp || argc < 1 || !argv)
81  return BRLCAD_ERROR;
82 
83  /* multiple arguments assumed to be multiple objects */
84  for (obj = 0; 2+obj < (size_t)argc; obj++) {
85 
86  /* load the constraint object */
87  dp = db_lookup(gedp->ged_wdbp->dbip, argv[2+obj], LOOKUP_QUIET);
88  if (dp == RT_DIR_NULL) {
89  bu_vls_printf(gedp->ged_result_str, "Unable to find %s in the database.\n", argv[2+obj]);
90  ret = BRLCAD_ERROR;
91  continue;
92  }
93 
94  bu_avs_init_empty(&avs);
95  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
96  bu_vls_printf(gedp->ged_result_str, "Cannot get constraints for %s\n", dp->d_namep);
97  ret = BRLCAD_ERROR;
98  }
99 
100  for (i=0, avpp = avs.avp; i < avs.count; i++, avpp++) {
101  bu_vls_printf(gedp->ged_result_str, "%s %s %s\n", argv[2+obj], avpp->name, avpp->value);
102  }
103 
104  bu_avs_free(&avs);
105  }
106 
107  return ret;
108 }
109 
110 
111 HIDDEN int
112 constraint_show(void *datap, int argc, const char *argv[])
113 {
114  size_t i, obj;
115  struct directory *dp;
116  struct bu_attribute_value_set avs;
117  struct bu_attribute_value_pair *avpp;
118  int ret = BRLCAD_OK;
119 
120  struct ged *gedp = (struct ged *)datap;
121 
122  if (!gedp || argc < 1 || !argv)
123  return BRLCAD_ERROR;
124 
125  /* multiple arguments assumed to be multiple objects */
126  for (obj = 0; 2+obj < (size_t)argc; obj++) {
127  bu_vls_printf(gedp->ged_result_str, "%s:\n", argv[2+obj]);
128 
129  /* load the constraint object */
130  dp = db_lookup(gedp->ged_wdbp->dbip, argv[2+obj], LOOKUP_QUIET);
131  if (dp == RT_DIR_NULL) {
132  bu_vls_printf(gedp->ged_result_str, "\tUnable to find %s in the database.\n", argv[2+obj]);
133  ret = BRLCAD_ERROR;
134  continue;
135  }
136 
137  bu_avs_init_empty(&avs);
138  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
139  bu_vls_printf(gedp->ged_result_str, "\tCannot get constraints for %s\n", dp->d_namep);
140  ret = BRLCAD_ERROR;
141  }
142 
143  for (i=0, avpp = avs.avp; i < avs.count; i++, avpp++) {
144  bu_vls_printf(gedp->ged_result_str, "\t%s = %s\n", avpp->name, avpp->value);
145  }
146 
147  bu_avs_free(&avs);
148  }
149 
150  return ret;
151 }
152 
153 
154 HIDDEN int
155 constraint_eval(void *datap, int argc, const char *argv[])
156 {
157  size_t i, obj;
158  struct directory *dp;
159  struct bu_attribute_value_set avs;
160  struct bu_attribute_value_pair *avpp;
161  int ret = BRLCAD_OK;
162 
163  struct ged *gedp = (struct ged *)datap;
164 
165  if (!gedp || argc < 1 || !argv)
166  return BRLCAD_ERROR;
167 
169 
170  /* multiple arguments assumed to be multiple objects */
171  for (obj = 0; 2+obj < (size_t)argc; obj++) {
172 
173  /* load the constraint object */
174  dp = db_lookup(gedp->ged_wdbp->dbip, argv[2+obj], LOOKUP_QUIET);
175  if (dp == RT_DIR_NULL) {
176  bu_vls_printf(gedp->ged_result_str, "Unable to find %s in the database.\n", argv[2+obj]);
177  ret = BRLCAD_ERROR;
178  continue;
179  }
180 
181  bu_avs_init_empty(&avs);
182  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
183  bu_vls_printf(gedp->ged_result_str, "Cannot get constraints from %s\n", dp->d_namep);
184  ret = BRLCAD_ERROR;
185  }
186 
187  for (i=0, avpp = avs.avp; i < avs.count; i++, avpp++) {
188  bu_vls_printf(gedp->ged_result_str, "Evaluating %s constraint: %s %s\n", argv[2+obj], avpp->name, avpp->value);
189  bu_vls_printf(gedp->ged_result_str, "<<constraint eval here>>\n");
190  }
191 
192  bu_avs_free(&avs);
193  }
194 
195  return ret;
196 }
197 
198 
199 HIDDEN void
200 constraint_usage(struct bu_vls *vp, const char *argv0)
201 {
202  static const char *usage1 = "set constraint_name [expression]";
203  static const char *usage2 = "{get|show|eval} constraint_name1 [constraint_name2 ...]";
204 
205  bu_vls_printf(vp, "Usage: %s %s\n", argv0, usage1);
206  bu_vls_printf(vp, " or %s %s\n", argv0, usage2);
207  bu_vls_printf(vp, " or %s help [command]\n", argv0);
208 }
209 
210 
211 HIDDEN int
212 constraint_help(void *datap, int argc, const char *argv[])
213 {
214  struct ged *gedp = (struct ged *)datap;
215  if (!gedp || argc < 1 || !argv)
216  return BRLCAD_ERROR;
217 
218  bu_vls_printf(gedp->ged_result_str, "Help for the %s command\n\n", argv[0]);
219 
220  constraint_usage(gedp->ged_result_str, argv[0]);
221 
223  "\nThis command lets you specify dimensional and geometric constraints.\n"
224  "These constraints and any specified parameters define explicit\n"
225  "relationships between geometry objects. Parametric constraints are\n"
226  "enforced during geometry editing when they are included in the boolean\n"
227  "recipe for a combination.\n\n");
228 
229  /* face may need to be a planar face */
230  /* objects will need to define a principle axis */
231 
232  bu_vls_printf(gedp->ged_result_str, "\nConstraint Expressions:\n");
233  bu_vls_printf(gedp->ged_result_str, "\tcoincident {{point point}|{point edge}|{edge edge}}\n"); /* mate */
234  bu_vls_printf(gedp->ged_result_str, "\t\tspecified entities stay connected\n");
235  bu_vls_printf(gedp->ged_result_str, "\tcollinear {line line}\n"); /* align */
236  bu_vls_printf(gedp->ged_result_str, "\t\tstraight edges are aligned along the same line\n");
237  bu_vls_printf(gedp->ged_result_str, "\tconcentric {circle circle}\n"); /* center */
238  bu_vls_printf(gedp->ged_result_str, "\t\tcircle/arc curves maintain same center point\n");
239  bu_vls_printf(gedp->ged_result_str, "\tfixed {point|edge|face|object}\n");
240  bu_vls_printf(gedp->ged_result_str, "\t\tspecified entity is immutable w.r.t. global coordinate system\n");
241  bu_vls_printf(gedp->ged_result_str, "\tparallel {{edge edge}|{edge face}|{face face}|{object object}}\n");
242  bu_vls_printf(gedp->ged_result_str, "\t\tspecified entities are parallel to each other\n");
243  bu_vls_printf(gedp->ged_result_str, "\tperpendicular {{edge edge}|{edge face}|{face face}|{object object}}\n");
244  bu_vls_printf(gedp->ged_result_str, "\t\tspecified entities are perpendicular (90 degrees angle to each other)\n");
245  bu_vls_printf(gedp->ged_result_str, "\thorizontal {{point point}|edge|vector}\n");
246  bu_vls_printf(gedp->ged_result_str, "\t\tspecified entities have X/Y values all set to match each other\n");
247  bu_vls_printf(gedp->ged_result_str, "\tvertical {{point point}|edge|vector}\n");
248  bu_vls_printf(gedp->ged_result_str, "\t\tspecified entities have Z values all set to match each other\n");
249  bu_vls_printf(gedp->ged_result_str, "\ttangent {point|edge|face|object} {point|edge|face|object}\n");
250  bu_vls_printf(gedp->ged_result_str, "\t\tspecified entities maintain contact (point sets overlap without intersecting)\n");
251  bu_vls_printf(gedp->ged_result_str, "\tsymmetric {{point point}|{curve curve}} line\n");
252  bu_vls_printf(gedp->ged_result_str, "\t\tspecified symmetry about an axis\n");
253  bu_vls_printf(gedp->ged_result_str, "\tequal {point|edge|face|object} {point|edge|face|object}\n");
254  bu_vls_printf(gedp->ged_result_str, "\t\tspecified values are set equal in magnitude/length/area to each other\n");
255  bu_vls_printf(gedp->ged_result_str, "\tformula {relationship}\n");
256  bu_vls_printf(gedp->ged_result_str, "\t\tgeneral parametric relationships using functions, variables, and values\n");
257 
258  bu_vls_printf(gedp->ged_result_str, "\nEntity Functions:\n");
259  bu_vls_printf(gedp->ged_result_str, "\tbisect(curve) => point\n");
260  bu_vls_printf(gedp->ged_result_str, "\tcenter(surface) => point\n");
261  bu_vls_printf(gedp->ged_result_str, "\tcentroid(object) => point\n");
262  bu_vls_printf(gedp->ged_result_str, "\tcurvature(curve1, t) => vector\n");
263 
264  bu_vls_printf(gedp->ged_result_str, "\nValue Functions:\n");
265  bu_vls_printf(gedp->ged_result_str, "\tangle(curve1, curve2) => value\n"); /* orient */
266  bu_vls_printf(gedp->ged_result_str, "\tarea(surface) => value\n");
267  bu_vls_printf(gedp->ged_result_str, "\tdiameter(arccurve) => value\n");
268  bu_vls_printf(gedp->ged_result_str, "\tdistance(entity, entity) => value\n");
269  bu_vls_printf(gedp->ged_result_str, "\thdistance(entity, entity) => value\n");
270  bu_vls_printf(gedp->ged_result_str, "\tlength(curve) => value\n");
271  bu_vls_printf(gedp->ged_result_str, "\tmagnitude(vector) => value\n");
272  bu_vls_printf(gedp->ged_result_str, "\tradius(arccurve) => value\n");
273  bu_vls_printf(gedp->ged_result_str, "\tvdistance(entity, entity) => value\n");
274 
275  bu_vls_printf(gedp->ged_result_str, "\nExamples:\n");
276  bu_vls_printf(gedp->ged_result_str, "\t%s set c1 coincident ell.V arb8.P[4]\n", argv[0]);
277  bu_vls_printf(gedp->ged_result_str, "\t%s set c2 collinear arb8.E[1] rpc.E[0]\n", argv[0]);
278  bu_vls_printf(gedp->ged_result_str, "\t%s set c3 tangent car terrain.r\n", argv[0]);
279  bu_vls_printf(gedp->ged_result_str, "\t%s set c4 equal ell.R[1] arb8.E[2]\n", argv[0]);
280  bu_vls_printf(gedp->ged_result_str, "\t%s set p0 formula ell.R[0]=10.0\n", argv[0]);
281  bu_vls_printf(gedp->ged_result_str, "\t%s set p1 formula eto.A<40.2\n", argv[0]);
282  bu_vls_printf(gedp->ged_result_str, "\t%s set p2 formula 4\n", argv[0]);
283  bu_vls_printf(gedp->ged_result_str, "\t%s set p3 formula ell.R[1] * p2\n", argv[0]);
284  bu_vls_printf(gedp->ged_result_str, "\t%s set p4 formula sph.R[0]=p3-10.5*magnitude(ell.V, argv[0])\n", argv[0]);
285  bu_vls_printf(gedp->ged_result_str, "\t%s get c1 c3\n", argv[0]);
286  bu_vls_printf(gedp->ged_result_str, "\t%s show c1 c2 c3 c4\n", argv[0]);
287  bu_vls_printf(gedp->ged_result_str, "\t%s eval c3 p4\n", argv[0]);
288 
289  return BRLCAD_OK;
290 }
291 
292 
293 int
294 ged_constraint(struct ged *gedp, int argc, const char *argv[])
295 {
296  /* Potential constraint attributes:
297  *
298  * attr set c1 cad:description "this keeps our car on the ground"
299  * attr set c1 cad:plot 0|1
300  * attr set c1 cad:reference 0|1
301  * attr set c1 cad:format value|name|expression (name=value)
302  * attr set c1 cad:disabled 0|1
303  */
304 
305  static struct bu_cmdtab pc_cmds[] = {
306  {"set", constraint_set},
307  {"get", constraint_get},
308  {"show", constraint_show},
309  {"eval", constraint_eval},
310  {"help", constraint_help},
311  {(const char *)NULL, BU_CMD_NULL}
312  };
313 
314  int ret;
315  int cmdret;
316 
317  /* initialize result */
318  bu_vls_trunc(gedp->ged_result_str, 0);
319 
320  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
321 
322  if (argc < 2) {
323  /* must be wanting help */
324  constraint_usage(gedp->ged_result_str, argv[0]);
325  return GED_HELP;
326  }
327  if (BU_STR_EQUIV(argv[1], "help")) {
328  constraint_help(gedp, argc, argv);
329  return GED_OK;
330  }
331 
332  if (argc < 3) {
333  /* must be confused */
334  constraint_usage(gedp->ged_result_str, argv[0]);
335  return GED_HELP;
336  }
337 
339 
340  /* this is only valid for v5 databases */
341  if (db_version(gedp->ged_wdbp->dbip) < 5) {
342  bu_vls_printf(gedp->ged_result_str, "Attributes are not available for this database format.\nPlease upgrade your database format using \"dbupgrade\" to enable attributes.");
343  return GED_ERROR;
344  }
345 
346  /* run our command */
347  ret = bu_cmd(pc_cmds, argc, argv, 1, gedp, &cmdret);
348  if (ret != BRLCAD_OK) {
349  constraint_usage(gedp->ged_result_str, argv[0]);
350  return GED_ERROR;
351  }
352  if (cmdret != BRLCAD_OK)
353  return GED_ERROR;
354 
355  return GED_OK;
356 }
357 
358 
359 /*
360  * Local Variables:
361  * tab-width: 8
362  * mode: C
363  * indent-tabs-mode: t
364  * c-file-style: "stroustrup"
365  * End:
366  * ex: shiftwidth=4 tabstop=8
367  */
Definition: cmd.h:48
#define GED_OK
Definition: ged.h:55
char * d_namep
pointer to name string
Definition: raytrace.h:859
HIDDEN int constraint_set(void *datap, int argc, const char *argv[])
Definition: constraint.c:29
void bu_avs_init_empty(struct bu_attribute_value_set *avp)
Definition: avs.c:36
int db5_update_attributes(struct directory *dp, struct bu_attribute_value_set *avsp, struct db_i *dbip)
Definition: attributes.c:285
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
int bu_avs_add(struct bu_attribute_value_set *avp, const char *attribute, const char *value)
Definition: avs.c:78
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define GED_CHECK_ARGC_GT_0(_gedp, _argc, _flags)
Definition: ged.h:202
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
int db_version(struct db_i *dbip)
Definition: db5_scan.c:414
HIDDEN int constraint_eval(void *datap, int argc, const char *argv[])
Definition: constraint.c:155
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
#define BU_CMD_NULL
Definition: cmd.h:37
const char * value
Definition: avs.h:62
int ged_constraint(struct ged *gedp, int argc, const char *argv[])
Definition: constraint.c:294
#define BU_AVS_INIT_ZERO
Definition: avs.h:112
#define GED_ERROR
Definition: ged.h:61
#define HIDDEN
Definition: common.h:86
HIDDEN int constraint_get(void *datap, int argc, const char *argv[])
Definition: constraint.c:70
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
struct bu_attribute_value_pair * avp
Definition: avs.h:89
void bu_vls_from_argv(struct bu_vls *vp, int argc, const char *argv[])
Definition: vls.c:532
HIDDEN int constraint_show(void *datap, int argc, const char *argv[])
Definition: constraint.c:112
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define BRLCAD_OK
Definition: defines.h:71
#define BU_STR_EQUIV(s1, s2)
Definition: str.h:135
HIDDEN int constraint_help(void *datap, int argc, const char *argv[])
Definition: constraint.c:212
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define RT_DIR_NULL
Definition: raytrace.h:875
#define GED_HELP
Definition: ged.h:62
HIDDEN void constraint_usage(struct bu_vls *vp, const char *argv0)
Definition: constraint.c:200
const char * name
Definition: avs.h:61
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
int db5_get_attributes(const struct db_i *dbip, struct bu_attribute_value_set *avs, const struct directory *dp)
Definition: db5_io.c:1027
Definition: vls.h:56
#define BRLCAD_ERROR
Definition: defines.h:72
void bu_avs_free(struct bu_attribute_value_set *avp)
Definition: avs.c:235
int bu_cmd(const struct bu_cmdtab *cmds, int argc, const char *argv[], int cmd_index, void *data, int *result)