BRL-CAD
brep_debug.cpp
Go to the documentation of this file.
1 /* B R E P _ D E B U G . C P P
2  * BRL-CAD
3  *
4  * Copyright (c) 2007-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 /** @addtogroup g_ */
21 /** @{ */
22 /** @file brep_debug.cpp
23  *
24  * brep debugging utilities
25  *
26  */
27 
28 #include "common.h"
29 
30 #include <vector>
31 #include <list>
32 #include <iostream>
33 #include <algorithm>
34 #include <set>
35 #include <utility>
36 
37 #include "poly2tri/poly2tri.h"
38 
39 #include "bu/log.h"
40 #include "bu/color.h"
41 #include "bu/str.h"
42 #include "bu/malloc.h"
43 #include "bu/list.h"
44 #include "bu/vls.h"
45 #include "vmath.h"
46 #include "plot3.h"
47 #include "brep.h"
48 #include "brep_debug.h"
49 #include "dvec.h"
50 
51 #include "raytrace.h"
52 #include "rtgeom.h"
53 #include "wdb.h"
54 
55 #include "brep_local.h"
56 
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
60  RT_EXPORT extern int brep_command(struct bu_vls *vls, const char *solid_name, const struct rt_tess_tol* ttol, const struct bn_tol* tol, struct brep_specific* bs, struct rt_brep_internal* bi, struct bn_vlblock *vbp, int argc, const char *argv[], char *commtag);
61  extern int single_conversion(struct rt_db_internal* intern, ON_Brep** brep, const struct db_i *dbip);
62  RT_EXPORT extern int brep_conversion(struct rt_db_internal* in, struct rt_db_internal* out, const struct db_i *dbip);
63  RT_EXPORT extern int brep_conversion_comb(struct rt_db_internal *old_internal, const char *name, const char *suffix, struct rt_wdb *wdbp, fastf_t local2mm);
64  RT_EXPORT extern int brep_intersect_point_point(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j);
65  RT_EXPORT extern int brep_intersect_point_curve(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j);
66  RT_EXPORT extern int brep_intersect_point_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j);
67  RT_EXPORT extern int brep_intersect_curve_curve(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j);
68  RT_EXPORT extern int brep_intersect_curve_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j);
69  RT_EXPORT extern int brep_intersect_surface_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j, struct bn_vlblock *vbp);
70  extern void rt_comb_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *UNUSED(tol), const struct db_i *dbip);
71 #ifdef __cplusplus
72 }
73 #endif
74 
75 extern void poly2tri_CDT(struct bu_list *vhead, ON_BrepFace &face, const struct rt_tess_tol *ttol, const struct bn_tol *tol, const struct rt_view_info *info, bool watertight = false, int plottype = 0, int num_points = -1.0);
76 
77 /********************************************************************************
78  * Auxiliary functions
79  ********************************************************************************/
80 
81 using namespace brlcad;
82 
83 FILE*
84 brep_plot_file(const char *pname)
85 {
86  static FILE* plot = NULL;
87 
88  if (plot != NULL) {
89  (void)fclose(plot);
90  plot = NULL;
91  }
92  if (pname == NULL) {
93  pname = "out.pl";
94  }
95  plot = fopen(pname, "w");
96  point_t min, max;
97  VSET(min, -2048, -2048, -2048);
98  VSET(max, 2048, 2048, 2048);
99  pdv_3space(plot, min, max);
100 
101  return plot;
102 }
103 
104 
105 #define ARB_FACE(valp, a, b, c, d) \
106  RT_ADD_VLIST(vhead, valp[a], BN_VLIST_LINE_MOVE); \
107  RT_ADD_VLIST(vhead, valp[b], BN_VLIST_LINE_DRAW); \
108  RT_ADD_VLIST(vhead, valp[c], BN_VLIST_LINE_DRAW); \
109  RT_ADD_VLIST(vhead, valp[d], BN_VLIST_LINE_DRAW);
110 
111 #define BB_PLOT_VLIST(min, max) { \
112  fastf_t pt[8][3]; \
113  VSET(pt[0], max[X], min[Y], min[Z]); \
114  VSET(pt[1], max[X], max[Y], min[Z]); \
115  VSET(pt[2], max[X], max[Y], max[Z]); \
116  VSET(pt[3], max[X], min[Y], max[Z]); \
117  VSET(pt[4], min[X], min[Y], min[Z]); \
118  VSET(pt[5], min[X], max[Y], min[Z]); \
119  VSET(pt[6], min[X], max[Y], max[Z]); \
120  VSET(pt[7], min[X], min[Y], max[Z]); \
121  ARB_FACE(pt, 0, 1, 2, 3); \
122  ARB_FACE(pt, 4, 0, 3, 7); \
123  ARB_FACE(pt, 5, 4, 7, 6); \
124  ARB_FACE(pt, 1, 5, 6, 2); \
125  }
126 
127 void
128 plotsurfaceleafs(SurfaceTree* surf) {
129  vect_t min;
130  vect_t max;
131  std::list<BBNode*> leaves;
132  surf->getLeaves(leaves);
133 
134  for (std::list<BBNode*>::iterator i = leaves.begin(); i != leaves.end(); i++) {
135  BBNode* bb = dynamic_cast<BBNode*>(*i);
136  if (bb->m_trimmed) {
137  COLOR_PLOT(255, 0, 0);
138  } else if (bb->m_checkTrim) {
139  COLOR_PLOT(0, 0, 255);
140  } else {
141  COLOR_PLOT(255, 0, 255);
142  }
143  /*
144  if (bb->m_xgrow) {
145  M_COLOR_PLOT(PURERED);
146  } else if (bb->m_ygrow) {
147  M_COLOR_PLOT(GREEN);
148  } else if (bb->m_zgrow) {
149  M_COLOR_PLOT(BLUE);
150  } else {
151  COLOR_PLOT(100, 100, 100);
152  }
153  */
154  //if ((!bb->m_trimmed) && (!bb->m_checkTrim)) {
155  if (false) {
156  //bb->GetBBox(min, max);
157  } else {
158  VSET(min, bb->m_u[0]+0.001, bb->m_v[0]+0.001, 0.0);
159  VSET(max, bb->m_u[1]-0.001, bb->m_v[1]-0.001, 0.0);
160  //VSET(min, bb->m_u[0], bb->m_v[0], 0.0);
161  //VSET(max, bb->m_u[1], bb->m_v[1], 0.0);
162  }
163  BB_PLOT(min, max);
164  //}
165  }
166  return;
167 }
168 
169 
170 unsigned int
171 plotsurfaceleafs(SurfaceTree* surf, struct bn_vlblock *vbp, bool dim3d)
172 {
173  register struct bu_list *vhead;
174  fastf_t min[3], max[3];
175  std::list<BBNode*> leaves;
176  surf->getLeaves(leaves);
177 
178  VSETALL(min, 0.0);
179 
180  ON_TextLog tl(stderr);
181 
182  vhead = rt_vlblock_find(vbp, PURERED);
183  RT_ADD_VLIST(vhead, min, BN_VLIST_LINE_MOVE);
184  vhead = rt_vlblock_find(vbp, BLUE);
185  RT_ADD_VLIST(vhead, min, BN_VLIST_LINE_MOVE);
186  vhead = rt_vlblock_find(vbp, MAGENTA);
187  RT_ADD_VLIST(vhead, min, BN_VLIST_LINE_MOVE);
188 
189  for (std::list<BBNode*>::iterator i = leaves.begin(); i != leaves.end(); i++) {
190  BBNode* bb = dynamic_cast<BBNode*>(*i);
191  if (bb->m_trimmed) {
192  vhead = rt_vlblock_find(vbp, PURERED);
193  } else if (bb->m_checkTrim) {
194  vhead = rt_vlblock_find(vbp, BLUE);
195  } else {
196  vhead = rt_vlblock_find(vbp, MAGENTA);
197  }
198  if (dim3d) {
199  bb->GetBBox(min, max);
200  } else {
201  VSET(min, bb->m_u[0]+0.001, bb->m_v[0]+0.001, 0.0);
202  VSET(max, bb->m_u[1]-0.001, bb->m_v[1]-0.001, 0.0);
203  }
204  BB_PLOT_VLIST(min, max);
205  }
206 
207  return leaves.size();
208 }
209 
210 
211 void
212 plottrimleafs(SurfaceTree* st, struct bn_vlblock *vbp, bool dim3d)
213 {
214  register struct bu_list *vhead;
215  vect_t min;
216  vect_t max;
217  std::list<BRNode*> leaves;
218  st->ctree->getLeaves(leaves);
219 
220  VSETALL(min, 0.0);
221 
222  ON_TextLog tl(stderr);
223 
224  vhead = rt_vlblock_find(vbp, PURERED);
225  RT_ADD_VLIST(vhead, min, BN_VLIST_LINE_MOVE);
226  vhead = rt_vlblock_find(vbp, BLUE);
227  RT_ADD_VLIST(vhead, min, BN_VLIST_LINE_MOVE);
228  vhead = rt_vlblock_find(vbp, MAGENTA);
229  RT_ADD_VLIST(vhead, min, BN_VLIST_LINE_MOVE);
230 
231  for (std::list<BRNode*>::iterator i = leaves.begin(); i != leaves.end(); i++) {
232  BRNode* bb = dynamic_cast<BRNode*>(*i);
233  if (bb->m_XIncreasing) {
234  vhead = rt_vlblock_find(vbp, GREEN);
235  } else {
236  vhead = rt_vlblock_find(vbp, BLUE);
237  }
238  bb->GetBBox(min, max);
239  if (dim3d) {
240  const ON_Surface *surf = st->getSurface();
241 
242  ON_3dPoint p1 = surf->PointAt(min[0], min[1]);
243  ON_3dPoint p2 = surf->PointAt(max[0], max[1]);
244  VMOVE(min, p1);
245  VMOVE(max, p2);
246  }
247  BB_PLOT_VLIST(min, max);
248  }
249 
250  return;
251 }
252 
253 
254 void
255 plotleaf3d(BBNode* bb,double within_distance_tol)
256 {
257  vect_t min;
258  vect_t max;
259  fastf_t u, v;
260  ON_2dPoint uv[2];
261  int trim1_status;
262  int trim2_status;
263  fastf_t closesttrim1;
264  fastf_t closesttrim2;
265 
266  if (bb->m_trimmed) {
267  COLOR_PLOT(255, 0, 0);
268  } else if (bb->m_checkTrim) {
269  COLOR_PLOT(0, 0, 255);
270  } else {
271  COLOR_PLOT(255, 0, 255);
272  }
273 
274  if (true) {
275  bb->GetBBox(min, max);
276  } else {
277  // VSET(min, bb->m_u[0]+0.001, bb->m_v[0]+0.001, 0.0);
278  // VSET(max, bb->m_u[1]-0.001, bb->m_v[1]-0.001, 0.0);
279  }
280  BB_PLOT(min, max);
281 
283  point_t a, b;
284  ON_3dPoint p;
285  BRNode* trimBR = NULL;
286  const ON_BrepFace* f = bb->m_face;
287  const ON_Surface* surf = f->SurfaceOf();
288  fastf_t uinc = (bb->m_u[1] - bb->m_u[0])/100.0;
289  fastf_t vinc = (bb->m_v[1] - bb->m_v[0])/100.0;
290  for (u=bb->m_u[0];u<bb->m_u[1];u=u+uinc) {
291  for (v=bb->m_v[0];v<bb->m_v[1];v=v+vinc) {
292  uv[0].x = u;
293  uv[0].y = v;
294  uv[1].x = u+uinc;
295  uv[1].y = v+vinc;
296  trim1_status = bb->isTrimmed(uv[0], &trimBR, closesttrim1,within_distance_tol);
297  trim2_status = bb->isTrimmed(uv[1], &trimBR, closesttrim2,within_distance_tol);
298 
299  if (((trim1_status != 1) || (fabs(closesttrim1) < within_distance_tol)) &&
300  ((trim2_status != 1) || (fabs(closesttrim2) < within_distance_tol))) {
301  p = surf->PointAt(uv[0].x, uv[0].y);
302  VMOVE(a, p);
303  p = surf->PointAt(uv[1].x, uv[1].y);
304  VMOVE(b, p);
305  LINE_PLOT(a, b);
306  }
307  }
308  }
309 
310  return;
311 }
312 
313 
314 void
315 plotleafuv(BBNode* bb)
316 {
317  vect_t min;
318  vect_t max;
319 
320  if (bb->m_trimmed) {
321  COLOR_PLOT(255, 0, 0);
322  } else if (bb->m_checkTrim) {
323  COLOR_PLOT(0, 0, 255);
324  } else {
325  COLOR_PLOT(255, 0, 255);
326  }
327 
328  if (false) {
329  // bb->GetBBox(min, max);
330  } else {
331  VSET(min, bb->m_u[0]+0.001, bb->m_v[0]+0.001, 0.0);
332  VSET(max, bb->m_u[1]-0.001, bb->m_v[1]-0.001, 0.0);
333  }
334  BB_PLOT(min, max);
335 
336  return;
337 }
338 
339 
340 void
341 plottrim(ON_BrepFace &face, struct bn_vlblock *vbp, int plotres, bool dim3d)
342 {
343  register struct bu_list *vhead;
344  const ON_Surface* surf = face.SurfaceOf();
345  fastf_t umin, umax;
346  fastf_t pt1[3], pt2[3];
347  ON_2dPoint from, to;
348 
349  ON_TextLog tl(stderr);
350 
351  vhead = rt_vlblock_find(vbp, YELLOW);
352 
353  surf->GetDomain(0, &umin, &umax);
354  for (int i = 0; i < face.LoopCount(); i++) {
355  ON_BrepLoop* loop = face.Loop(i);
356  // for each trim
357  for (int j = 0; j < loop->m_ti.Count(); j++) {
358  ON_BrepTrim& trim = face.Brep()->m_T[loop->m_ti[j]];
359  const ON_Curve* trimCurve = trim.TrimCurveOf();
360  //trimCurve->Dump(tl);
361 
362  ON_Interval dom = trimCurve->Domain();
363  // XXX todo: dynamically sample the curve
364  for (int k = 1; k <= plotres; k++) {
365  ON_3dPoint p = trimCurve->PointAt(dom.ParameterAt((double) (k - 1) / (double) plotres));
366  if (dim3d)
367  p = surf->PointAt(p.x, p.y);
368  VMOVE(pt1, p);
369  p = trimCurve->PointAt(dom.ParameterAt((double) k / (double) plotres));
370  if (dim3d)
371  p = surf->PointAt(p.x, p.y);
372  VMOVE(pt2, p);
373  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
374  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
375  }
376  }
377  }
378 
379  return;
380 }
381 
382 
383 void
384 plottrim2d(ON_BrepFace &face, struct bn_vlblock *vbp, int plotres)
385 {
386  register struct bu_list *vhead;
387  const ON_Surface* surf = face.SurfaceOf();
388  fastf_t umin, umax;
389  fastf_t pt1[3], pt2[3];
390  ON_2dPoint from, to;
391 
392  ON_TextLog tl(stderr);
393 
394  vhead = rt_vlblock_find(vbp, YELLOW);
395 
396  surf->GetDomain(0, &umin, &umax);
397  for (int i = 0; i < face.LoopCount(); i++) {
398  ON_BrepLoop* loop = face.Loop(i);
399  // for each trim
400  for (int j = 0; j < loop->m_ti.Count(); j++) {
401  ON_BrepTrim& trim = face.Brep()->m_T[loop->m_ti[j]];
402  const ON_Curve* trimCurve = trim.TrimCurveOf();
403  //trimCurve->Dump(tl);
404 
405  ON_Interval dom = trimCurve->Domain();
406  // XXX todo: dynamically sample the curve
407  for (int k = 1; k <= plotres; k++) {
408  ON_3dPoint p = trimCurve->PointAt(dom.ParameterAt((double) (k - 1) / (double) plotres));
409  //p = surf->PointAt(p.x, p.y);
410  VMOVE(pt1, p);
411  p = trimCurve->PointAt(dom.ParameterAt((double) k / (double) plotres));
412  //p = surf->PointAt(p.x, p.y);
413  VMOVE(pt2, p);
414  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
415  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
416  }
417  }
418  }
419 
420  return;
421 }
422 
423 
424 void
425 plotUVDomain2d(ON_BrepFace &face, struct bn_vlblock *vbp)
426 {
427  register struct bu_list *vhead;
428  const ON_Surface* surf = face.SurfaceOf();
429  fastf_t umin, umax, urange;
430  fastf_t vmin, vmax, vrange;
431  fastf_t pt1[3], pt2[3];
432  ON_2dPoint from, to;
433 
434  ON_TextLog tl(stderr);
435 
436  vhead = rt_vlblock_find(vbp, PURERED);
437 
438  double width, height;
439  ON_BoundingBox loop_bb;
440  ON_BoundingBox trim_bb;
441 #ifndef RESETDOMAIN
442  if (face.GetSurfaceSize(&width, &height)) {
443  face.SetDomain(0, 0.0, width);
444  face.SetDomain(1, 0.0, height);
445 
446  }
447 #endif
448  surf->GetDomain(0, &umin, &umax);
449  surf->GetDomain(1, &vmin, &vmax);
450  // add a little offset so we can see the boundary curves
451  urange = umax - umin;
452  vrange = vmax - vmin;
453  umin = umin - 0.01*urange;
454  vmin = vmin - 0.01*vrange;
455  umax = umax + 0.01*urange;
456  vmax = vmax + 0.01*vrange;
457 
458  //umin
459  VSET(pt1, umin, vmin, 0.0);
460  VSET(pt2, umin, vmax, 0.0);
461  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
462  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
463  // umax
464  VSET(pt1, umax, vmin, 0.0);
465  VSET(pt2, umax, vmax, 0.0);
466  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
467  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
468  //vmin
469  VSET(pt1, umin, vmin, 0.0);
470  VSET(pt2, umax, vmin, 0.0);
471  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
472  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
473  //vmax
474  VSET(pt1, umin, vmax, 0.0);
475  VSET(pt2, umax, vmax, 0.0);
476  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
477  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
478 
479  return;
480 }
481 
482 
483 void
484 plottrim(ON_BrepTrim& trim, struct bn_vlblock *vbp, int plotres, bool dim3d)
485 {
486  register struct bu_list *vhead;
487  ON_BrepFace *face = trim.Face();
488  point_t pt;
489 
490  ON_TextLog tl(stderr);
491 
492  vhead = rt_vlblock_find(vbp, YELLOW);
493 
494  const ON_Curve* trimCurve = trim.TrimCurveOf();
495  ON_Interval dom = trimCurve->Domain();
496 
497  //trimCurve->Dump(tl);
498  for (int k = 0; k <= plotres; ++k) {
499  ON_3dPoint p = trimCurve->PointAt(dom.ParameterAt((double)k / plotres));
500 
501  if (dim3d) {
502  p = face->PointAt(p.x, p.y);
503  }
504  VMOVE(pt, p);
505 
506  if (k != 0) {
507  RT_ADD_VLIST(vhead, pt, BN_VLIST_LINE_DRAW);
508  } else {
509  RT_ADD_VLIST(vhead, pt, BN_VLIST_LINE_MOVE);
510  }
511  }
512  return;
513 }
514 
515 
516 void
517 plottrimdirection(ON_BrepFace &face, struct bn_vlblock *vbp, int plotres)
518 {
519  register struct bu_list *vhead;
520  const ON_Surface* surf = face.SurfaceOf();
521  fastf_t umin, umax;
522  fastf_t pt1[3], pt2[3];
523  ON_2dPoint from, to;
524 
525  ON_TextLog tl(stderr);
526 
527  vhead = rt_vlblock_find(vbp, GREEN);
528 
529  surf->GetDomain(0, &umin, &umax);
530  for (int i = 0; i < face.LoopCount(); i++) {
531  ON_BrepLoop* loop = face.Loop(i);
532  // for each trim
533  for (int j = 0; j < loop->m_ti.Count(); j++) {
534  ON_BrepTrim& trim = face.Brep()->m_T[loop->m_ti[j]];
535  const ON_Curve* trimCurve = trim.TrimCurveOf();
536  //trimCurve->Dump(tl);
537 
538  int knotcnt = trimCurve->SpanCount();
539  fastf_t *knots = new fastf_t[knotcnt + 1];
540 
541  trimCurve->GetSpanVector(knots);
542  for (int k = 1; k <= knotcnt; k++) {
543  fastf_t dist = knots[k] - knots[k-1];
544  fastf_t step = dist/plotres;
545  for (fastf_t t=knots[k-1]+step; t<=knots[k]; t=t+step) {
546  ON_3dPoint p = trimCurve->PointAt(t);
547  p = surf->PointAt(p.x, p.y);
548  ON_3dPoint prev = trimCurve->PointAt(t-step*0.1);
549  prev = surf->PointAt(prev.x, prev.y);
550  ON_3dVector N = surf->NormalAt(p.x, p.y);
551  N.Unitize();
552  ON_3dVector tan = p - prev;
553  tan.Unitize();
554  prev = p - tan;
555  ON_3dVector A = ON_CrossProduct(tan, N);
556  A.Unitize();
557  ON_3dVector B = ON_CrossProduct(N, tan);
558  B.Unitize();
559  ON_3dPoint a = prev + A;
560  ON_3dPoint b = prev + B;
561  VMOVE(pt1, p);
562  VMOVE(pt2, a);
563  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
564  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
565  VMOVE(pt2, b);
566  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
567  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
568  }
569  }
570  }
571  }
572 
573  return;
574 }
575 
576 
577 void
578 plotsurface(ON_Surface &surf, struct bn_vlblock *vbp, int isocurveres, int gridres, const int red = 200, const int green = 200, const int blue = 200)
579 {
580  register struct bu_list *vhead;
581  fastf_t pt1[3], pt2[3];
582  ON_2dPoint from, to;
583  fastf_t hsv[3];
584  unsigned char fill_rgb[3];
585 
586  VSET(fill_rgb,(unsigned char)red,(unsigned char)green,(unsigned char)blue);
587  bu_rgb_to_hsv(fill_rgb,hsv);
588  // simply fill with 50% lightness/value of outline
589  hsv[2] = hsv[2] * 0.5;
590  bu_hsv_to_rgb(hsv,fill_rgb);
591 
592 
593  vhead = rt_vlblock_find(vbp, red, green, blue);
594 
595  ON_Interval udom = surf.Domain(0);
596  ON_Interval vdom = surf.Domain(1);
597 
598  for (int u = 0; u <= gridres; u++) {
599  if (u == 0 || u == gridres) {
600  vhead = rt_vlblock_find(vbp, red, green, blue);
601  } else {
602  vhead = rt_vlblock_find(vbp, (int)(fill_rgb[0]), (int)(fill_rgb[1]), (int)(fill_rgb[2]));
603  }
604  for (int v = 1; v <= isocurveres; v++) {
605  ON_3dPoint p = surf.PointAt(udom.ParameterAt((double)u/(double)gridres), vdom.ParameterAt((double)(v-1)/(double)isocurveres));
606  VMOVE(pt1, p);
607  p = surf.PointAt(udom.ParameterAt((double)u/(double)gridres), vdom.ParameterAt((double)v/(double)isocurveres));
608  VMOVE(pt2, p);
609  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
610  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
611  }
612  }
613 
614  for (int v = 0; v <= gridres; v++) {
615  if (v == 0 || v == gridres) {
616  vhead = rt_vlblock_find(vbp, red, green, blue);
617  } else {
618  vhead = rt_vlblock_find(vbp, (int)(fill_rgb[0]), (int)(fill_rgb[1]), (int)(fill_rgb[2]));
619  }
620  for (int u = 1; u <= isocurveres; u++) {
621  ON_3dPoint p = surf.PointAt(udom.ParameterAt((double)(u-1)/(double)isocurveres), vdom.ParameterAt((double)v/(double)gridres));
622  VMOVE(pt1, p);
623  p = surf.PointAt(udom.ParameterAt((double)u/(double)isocurveres), vdom.ParameterAt((double)v/(double)gridres));
624  VMOVE(pt2, p);
625  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
626  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
627  }
628  }
629  return;
630 }
631 
632 
633 void
634 plotsurfacenormals(ON_Surface &surf, struct bn_vlblock *vbp, int gridres)
635 {
636  register struct bu_list *vhead;
637  fastf_t pt1[3], pt2[3];
638  ON_2dPoint from, to;
639 
640  vhead = rt_vlblock_find(vbp, GREEN);
641 
642  ON_Interval udom = surf.Domain(0);
643  ON_Interval vdom = surf.Domain(1);
644 
645  for (int u = 0; u <= gridres; u++) {
646  for (int v = 1; v <= gridres; v++) {
647  ON_3dPoint p = surf.PointAt(udom.ParameterAt((double)u/(double)gridres), vdom.ParameterAt((double)(v-1)/(double)gridres));
648  ON_3dVector n = surf.NormalAt(udom.ParameterAt((double)u/(double)gridres), vdom.ParameterAt((double)(v-1)/(double)gridres));
649  n.Unitize();
650  VMOVE(pt1, p);
651  VSCALE(pt2, n, surf.BoundingBox().Diagonal().Length()*0.1);
652  VADD2(pt2, pt1, pt2);
653  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
654  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
655  }
656  }
657  return;
658 }
659 
660 
661 void
662 plotsurfaceknots(ON_Surface &surf, struct bn_vlblock *vbp, bool dim3d)
663 {
664  register struct bu_list *vhead;
665  fastf_t pt1[3], pt2[3];
666  ON_2dPoint from, to;
667  int spanu_cnt = surf.SpanCount(0);
668  int spanv_cnt = surf.SpanCount(1);
669  fastf_t *spanu = NULL;
670  fastf_t *spanv = NULL;
671  spanu = new fastf_t[spanu_cnt+1];
672  spanv = new fastf_t[spanv_cnt+1];
673 
674 #ifndef RESETDOMAIN
675  double width, height;
676  if (surf.GetSurfaceSize(&width, &height)) {
677  surf.SetDomain(0, 0.0, width);
678  surf.SetDomain(1, 0.0, height);
679 
680  }
681 #endif
682 
683  surf.GetSpanVector(0, spanu);
684  surf.GetSpanVector(1, spanv);
685 
686  vhead = rt_vlblock_find(vbp, GREEN);
687 
688  ON_Interval udom = surf.Domain(0);
689  ON_Interval vdom = surf.Domain(1);
690 
691  if (dim3d) {
692  for (int u = 0; u <= spanu_cnt; u++) {
693  for (int v = 0; v <= spanv_cnt; v++) {
694  ON_3dPoint p = surf.PointAt(spanu[u], spanv[v]);
695  ON_3dVector n = surf.NormalAt(spanu[u], spanv[v]);
696  n.Unitize();
697  VMOVE(pt1, p);
698  VSCALE(pt2, n, 3.0);
699  VADD2(pt2, pt1, pt2);
700  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
701  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
702  }
703  }
704  } else {
705  for (int u = 0; u <= spanu_cnt; u++) {
706  for (int v = 0; v <= spanv_cnt; v++) {
707  VSET(pt1, spanu[u], spanv[v], 0.0);
708  RT_ADD_VLIST(vhead, pt1, BN_VLIST_POINT_DRAW);
709  }
710  }
711  }
712  return;
713 }
714 
715 
716 void
717 plotcurve(ON_Curve &curve, struct bn_vlblock *vbp, int plotres, const int red = 255, const int green = 255, const int blue = 0)
718 {
719  register struct bu_list *vhead;
720  fastf_t pt1[3], pt2[3];
721  ON_2dPoint from, to;
722 
723  vhead = rt_vlblock_find(vbp, red, green, blue);
724 
725  if (curve.IsLinear()) {
726  /*
727  ON_BrepVertex& v1 = face.Brep()->m_V[trim.m_vi[0]];
728  ON_BrepVertex& v2 = face.Brep()->m_V[trim.m_vi[1]];
729  VMOVE(pt1, v1.Point());
730  VMOVE(pt2, v2.Point());
731  LINE_PLOT(pt1, pt2);
732  */
733 
734  int knotcnt = curve.SpanCount();
735  fastf_t *knots = new fastf_t[knotcnt + 1];
736 
737  curve.GetSpanVector(knots);
738  for (int i = 1; i <= knotcnt; i++) {
739  ON_3dPoint p = curve.PointAt(knots[i - 1]);
740  VMOVE(pt1, p);
741  p = curve.PointAt(knots[i]);
742  VMOVE(pt2, p);
743  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
744  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
745  }
746 
747  } else {
748  ON_Interval dom = curve.Domain();
749  // XXX todo: dynamically sample the curve
750  for (int i = 1; i <= plotres; i++) {
751  ON_3dPoint p = curve.PointAt(dom.ParameterAt((double) (i - 1)
752  / (double)plotres));
753  VMOVE(pt1, p);
754  p = curve.PointAt(dom.ParameterAt((double) i / (double)plotres));
755  VMOVE(pt2, p);
756  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
757  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
758  }
759  }
760  return;
761 }
762 
763 
764 void
765 plotpoint(const ON_3dPoint &point, struct bn_vlblock *vbp, const int red = 255, const int green = 255, const int blue = 0)
766 {
767  register struct bu_list *vhead;
768  ON_3dPoint pointsize(4.0,0,0);
769  vhead = rt_vlblock_find(vbp, red, green, blue);
770  RT_ADD_VLIST(vhead, pointsize, BN_VLIST_POINT_SIZE);
771  RT_ADD_VLIST(vhead, point, BN_VLIST_POINT_DRAW);
772  return;
773 }
774 
775 
776 void plotcurveonsurface(ON_Curve *curve,
777  ON_Surface *surface,
778  struct bn_vlblock *vbp,
779  int plotres,
780  const int red = 255,
781  const int green = 255,
782  const int blue = 0)
783 {
784  if (curve->Dimension() != 2)
785  return;
786  register struct bu_list *vhead;
787  vhead = rt_vlblock_find(vbp, red, green, blue);
788 
789  for (int i = 0; i <= plotres; i++) {
790  ON_2dPoint pt2d;
791  ON_3dPoint pt3d;
792  ON_3dPoint pt1, pt2;
793  pt2d = curve->PointAt(curve->Domain().ParameterAt((double)i/plotres));
794  pt3d = surface->PointAt(pt2d.x, pt2d.y);
795  pt1 = pt2;
796  pt2 = pt3d;
797  if (i != 0) {
798  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
799  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
800  }
801  }
802  return;
803 }
804 
805 
806 void
807 plottrim(const ON_Curve &curve, double from, double to)
808 {
809  point_t pt1, pt2;
810  // XXX todo: dynamically sample the curve
811  for (int i = 0; i <= 10000; i++) {
812  ON_3dPoint p = curve.PointAt(from + (to-from)*(double)i/10000.0);//dom.ParameterAt((double)i/10000.0));
813  VMOVE(pt2, p);
814  if (i != 0) {
815  LINE_PLOT(pt1, pt2);
816  }
817  VMOVE(pt1, p);
818  }
819 }
820 
821 
822 void
823 plottrim(ON_Curve &curve)
824 {
825  point_t pt1, pt2;
826  // XXX todo: dynamically sample the curve
827  ON_Interval dom = curve.Domain();
828  for (int i = 0; i <= 10000; i++) {
829  ON_3dPoint p = curve.PointAt(dom.ParameterAt((double)i/10000.0));
830  VMOVE(pt2, p);
831  if (i != 0) {
832  LINE_PLOT(pt1, pt2);
833  }
834  VMOVE(pt1, p);
835  }
836 }
837 
838 
839 int
840 brep_info(struct brep_specific* bs, struct bu_vls *vls)
841 {
842  ON_Brep *brep = bs->brep;
843  bu_vls_printf(vls, "surfaces: %d\n", brep->m_S.Count());
844  bu_vls_printf(vls, "3d curve: %d\n", brep->m_C3.Count());
845  bu_vls_printf(vls, "2d curves: %d\n", brep->m_C2.Count());
846  bu_vls_printf(vls, "vertices: %d\n", brep->m_V.Count());
847  bu_vls_printf(vls, "edges: %d\n", brep->m_E.Count());
848  bu_vls_printf(vls, "trims: %d\n", brep->m_T.Count());
849  bu_vls_printf(vls, "loops: %d\n", brep->m_L.Count());
850  bu_vls_printf(vls, "faces: %d\n", brep->m_F.Count());
851 
852  return 0;
853 }
854 
855 
856 int
857 brep_surface_info(struct brep_specific* bs, struct bu_vls *vls, int si)
858 {
859  ON_wString wonstr;
860  ON_TextLog info_output(wonstr);
861  ON_Brep *brep = bs->brep;
862  if (brep == NULL) {
863  return -1;
864  }
865  if (!brep->IsValid(&info_output)) {
866  bu_log("brep is NOT valid");
867  }
868  if ((si >= 0) && (si < brep->m_S.Count())) {
869  const ON_Surface* srf = brep->m_S[si];
870  if (srf) {
871  //ON_wString wonstr;
872  //ON_TextLog info_output(wonstr);
873  ON_Interval udom = srf->Domain(0);
874  ON_Interval vdom = srf->Domain(1);
875  const char* s = srf->ClassId()->ClassName();
876  if (!s)
877  s = "";
878  bu_vls_printf(vls, "surface[%2d]: %s u(%g, %g) v(%g, %g)\n",
879  si, s,
880  udom[0], udom[1],
881  vdom[0], vdom[1]
882  );
883  bu_vls_printf(vls, "NURBS form of Surface:\n");
884  ON_NurbsSurface *nsrf = ON_NurbsSurface::New();
885  srf->GetNurbForm(*nsrf, 0.0);
886  nsrf->Dump(info_output);
887  ON_String onstr = ON_String(wonstr);
888  const char *infodesc = onstr.Array();
889  bu_vls_strcat(vls, infodesc);
890  delete nsrf;
891  } else {
892  bu_vls_printf(vls, "surface[%2d]: NULL\n", si);
893  }
894  }
895 
896  return 0;
897 }
898 
899 
900 int
901 brep_surface_bezier_info(struct brep_specific* bs, struct bu_vls *vls, int si)
902 {
903  ON_wString wonstr;
904  ON_TextLog info_output(wonstr);
905  ON_Brep *brep = bs->brep;
906  if (brep == NULL) {
907  return -1;
908  }
909  if (!brep->IsValid(&info_output)) {
910  bu_log("brep is NOT valid");
911  }
912 
913  if ((si >= 0) && (si < brep->m_S.Count())) {
914  const ON_Surface* srf = brep->m_S[si];
915  if (srf) {
916  //ON_wString wonstr;
917  //ON_TextLog info_output(wonstr);
918  ON_Interval udom = srf->Domain(0);
919  ON_Interval vdom = srf->Domain(1);
920  const char* s = srf->ClassId()->ClassName();
921  if (!s)
922  s = "";
923  bu_vls_printf(vls, "surface[%2d]: %s u(%g, %g) v(%g, %g)\n",
924  si, s,
925  udom[0], udom[1],
926  vdom[0], vdom[1]
927  );
928  ON_NurbsSurface *nsrf = ON_NurbsSurface::New();
929  srf->GetNurbForm(*nsrf, 0.0);
930  int knotlength0 = nsrf->m_order[0] + nsrf->m_cv_count[0] - 2;
931  int knotlength1 = nsrf->m_order[1] + nsrf->m_cv_count[1] - 2;
932  int order0 = nsrf->m_order[0];
933  int order1 = nsrf->m_order[1];
934  fastf_t *knot0 = nsrf->m_knot[0];
935  fastf_t *knot1 = nsrf->m_knot[1];
936  int cnt = 0;
937  bu_vls_printf(vls, "bezier patches:\n");
938  for (int i = 0; i < knotlength0; ++i) {
939  for (int j = 0; j < knotlength1; ++j) {
940  ON_BezierSurface *bezier = new ON_BezierSurface;
941  if (nsrf->ConvertSpanToBezier(i, j, *bezier)) {
942  info_output.Print("NO.%d segment\n", ++cnt);
943  info_output.Print("spanindex u from %d to %d\n", i + order0 - 2, i + order0 - 1);
944  info_output.Print("spanindex v from %d to %d\n", j + order1 - 2, j + order1 - 1);
945  info_output.Print("knot u from %.2f to %.2f\n ", knot0[i + order0 - 2], knot0[i + order0 - 1]);
946  info_output.Print("knot v from %.2f to %.2f\n ", knot1[j + order1 - 2], knot1[j + order1 - 1]);
947  info_output.Print("domain u(%g, %g)\n", bezier->Domain(0)[0], bezier->Domain(0)[1]);
948  info_output.Print("domain v(%g, %g)\n", bezier->Domain(1)[0], bezier->Domain(1)[1]);
949  bezier->Dump(info_output);
950  info_output.Print("\n");
951  }
952  delete bezier;
953  }
954  }
955  ON_String onstr = ON_String(wonstr);
956  const char *infodesc = onstr.Array();
957  bu_vls_strcat(vls, infodesc);
958  delete nsrf;
959  } else {
960  bu_vls_printf(vls, "surface[%2d]: NULL\n", si);
961  }
962  }
963  return 0;
964 }
965 
966 
967 int
968 brep_face_info(struct brep_specific* bs, struct bu_vls *vls, int fi)
969 {
970  ON_wString s;
971  ON_TextLog dump(s);
972  ON_Brep *brep = bs->brep;
973  if (brep == NULL) {
974  return -1;
975  }
976  if (!brep->IsValid(&dump)) {
977  bu_log("brep is NOT valid");
978  }
979 
980  if (!((fi >= 0) && (fi < brep->m_F.Count())))
981  return 0;
982  //ON_wString s;
983  //ON_TextLog dump(s);
984  const ON_BrepFace& face = brep->m_F[fi];
985  const ON_Surface* face_srf = face.SurfaceOf();
986  dump.Print("face[%2d]: surface(%d) reverse(%d) loops(", fi, face.m_si, face.m_bRev);
987  int fli;
988  for (fli = 0; fli < face.m_li.Count(); fli++) {
989  dump.Print((fli) ? ", %d" : "%d", face.m_li[fli]);
990  }
991  dump.Print(")\n");
992  dump.PushIndent();
993 
994  for (fli = 0; fli < face.m_li.Count(); fli++) {
995  const int li = face.m_li[fli];
996  const ON_BrepLoop& loop = brep->m_L[li];
997  const char* sLoopType = 0;
998  switch (loop.m_type) {
999  case ON_BrepLoop::unknown:
1000  sLoopType = "unknown";
1001  break;
1002  case ON_BrepLoop::outer:
1003  sLoopType = "outer";
1004  break;
1005  case ON_BrepLoop::inner:
1006  sLoopType = "inner";
1007  break;
1008  case ON_BrepLoop::slit:
1009  sLoopType = "slit";
1010  break;
1011  case ON_BrepLoop::crvonsrf:
1012  sLoopType = "crvonsrf";
1013  break;
1014  default:
1015  sLoopType = "unknown";
1016  break;
1017  }
1018  dump.Print("loop[%2d]: type(%s) %d trims(", li, sLoopType, loop.m_ti.Count());
1019  int lti;
1020  for (lti = 0; lti < loop.m_ti.Count(); lti++) {
1021  dump.Print((lti) ? ", %d" : "%d", loop.m_ti[lti]);
1022  }
1023  dump.Print(")\n");
1024  dump.PushIndent();
1025  for (lti = 0; lti < loop.m_ti.Count(); lti++) {
1026  const int ti = loop.m_ti[lti];
1027  const ON_BrepTrim& trim = brep->m_T[ti];
1028  const char* sTrimType = "?";
1029  const char* sTrimIso = "-?";
1030  const ON_Curve* c2 = trim.TrimCurveOf();
1031  ON_NurbsCurve* nc2 = ON_NurbsCurve::New();
1032  c2->GetNurbForm(*nc2, 0.0);
1033  ON_3dPoint trim_start, trim_end;
1034  switch (trim.m_type) {
1035  case ON_BrepTrim::unknown:
1036  sTrimType = "unknown ";
1037  break;
1038  case ON_BrepTrim::boundary:
1039  sTrimType = "boundary";
1040  break;
1041  case ON_BrepTrim::mated:
1042  sTrimType = "mated ";
1043  break;
1044  case ON_BrepTrim::seam:
1045  sTrimType = "seam ";
1046  break;
1047  case ON_BrepTrim::singular:
1048  sTrimType = "singular";
1049  break;
1050  case ON_BrepTrim::crvonsrf:
1051  sTrimType = "crvonsrf";
1052  break;
1053  default:
1054  sTrimType = "unknown";
1055  break;
1056  }
1057  switch (trim.m_iso) {
1058  case ON_Surface::not_iso:
1059  sTrimIso = "";
1060  break;
1061  case ON_Surface::x_iso:
1062  sTrimIso = "-u iso";
1063  break;
1064  case ON_Surface::W_iso:
1065  sTrimIso = "-west side iso";
1066  break;
1067  case ON_Surface::E_iso:
1068  sTrimIso = "-east side iso";
1069  break;
1070  case ON_Surface::y_iso:
1071  sTrimIso = "-v iso";
1072  break;
1073  case ON_Surface::S_iso:
1074  sTrimIso = "-south side iso";
1075  break;
1076  case ON_Surface::N_iso:
1077  sTrimIso = "-north side iso";
1078  break;
1079  default:
1080  sTrimIso = "-unknown_iso_flag";
1081  break;
1082  }
1083  dump.Print("trim[%2d]: edge(%2d) v0(%2d) v1(%2d) tolerance(%g, %g)\n", ti, trim.m_ei, trim.m_vi[0], trim.m_vi[1], trim.m_tolerance[0], trim.m_tolerance[1]);
1084  dump.PushIndent();
1085  dump.Print("type(%s%s) rev3d(%d) 2d_curve(%d)\n", sTrimType, sTrimIso, trim.m_bRev3d, trim.m_c2i);
1086  if (c2) {
1087  trim_start = trim.PointAtStart();
1088  trim_end = trim.PointAtEnd();
1089  dump.Print("domain(%g, %g) start(%g, %g) end(%g, %g)\n", trim.Domain()[0], trim.Domain()[1], trim_start.x, trim_start.y, trim_end.x, trim_end.y);
1090  if (0 != face_srf) {
1091  ON_3dPoint trim_srfstart = face_srf->PointAt(trim_start.x, trim_start.y);
1092  ON_3dPoint trim_srfend = face_srf->PointAt(trim_end.x, trim_end.y);
1093  dump.Print("surface points start(%g, %g, %g) end(%g, %g, %g)\n", trim_srfstart.x, trim_srfstart.y, trim_srfstart.z, trim_srfend.x, trim_srfend.y, trim_srfend.z);
1094  }
1095  } else {
1096  dump.Print("domain(%g, %g) start(?, ?) end(?, ?)\n", trim.Domain()[0], trim.Domain()[1]);
1097  }
1098  dump.PopIndent();
1099  }
1100  dump.PopIndent();
1101  }
1102  dump.PopIndent();
1103 
1104  ON_String ss = s;
1105  bu_vls_printf(vls, "%s\n", ss.Array());
1106 
1107  return 0;
1108 }
1109 
1110 
1111 int
1112 brep_trim_info(struct brep_specific* bs, struct bu_vls *vls, int ti)
1113 {
1114  ON_Brep* brep = bs->brep;
1115  ON_wString wstr;
1116  ON_TextLog dump(wstr);
1117  if (brep == NULL) {
1118  return -1;
1119  }
1120  if (!brep->IsValid(&dump)) {
1121  bu_log("brep is NOT valid");
1122  }
1123 
1124  if (!((ti >= 0) && (ti < brep->m_T.Count())))
1125  return 0;
1126  const ON_BrepTrim &trim = brep->m_T[ti];
1127  const ON_Surface* trim_srf = trim.SurfaceOf();
1128  const ON_BrepLoop &loop = brep->m_L[trim.m_li];
1129  const ON_BrepFace &face = brep->m_F[loop.m_fi];
1130  const char* sTrimType = "?";
1131  const char* sTrimIso = "-?";
1132  const ON_Curve* c2 = trim.TrimCurveOf();
1133  ON_NurbsCurve* nc2 = ON_NurbsCurve::New();
1134  c2->GetNurbForm(*nc2, 0.0);
1135  ON_3dPoint trim_start, trim_end;
1136  dump.Print("trim[%2d]: surface(%2d) faces(%2d) loops(%2d)\n", ti, face.m_si, face.m_face_index, loop.m_loop_index);
1137  switch (trim.m_type) {
1138  case ON_BrepTrim::unknown:
1139  sTrimType = "unknown ";
1140  break;
1141  case ON_BrepTrim::boundary:
1142  sTrimType = "boundary";
1143  break;
1144  case ON_BrepTrim::mated:
1145  sTrimType = "mated ";
1146  break;
1147  case ON_BrepTrim::seam:
1148  sTrimType = "seam ";
1149  break;
1150  case ON_BrepTrim::singular:
1151  sTrimType = "singular";
1152  break;
1153  case ON_BrepTrim::crvonsrf:
1154  sTrimType = "crvonsrf";
1155  break;
1156  default:
1157  sTrimType = "unknown";
1158  break;
1159  }
1160  switch (trim.m_iso) {
1161  case ON_Surface::not_iso:
1162  sTrimIso = "";
1163  break;
1164  case ON_Surface::x_iso:
1165  sTrimIso = "-u iso";
1166  break;
1167  case ON_Surface::W_iso:
1168  sTrimIso = "-west side iso";
1169  break;
1170  case ON_Surface::E_iso:
1171  sTrimIso = "-east side iso";
1172  break;
1173  case ON_Surface::y_iso:
1174  sTrimIso = "-v iso";
1175  break;
1176  case ON_Surface::S_iso:
1177  sTrimIso = "-south side iso";
1178  break;
1179  case ON_Surface::N_iso:
1180  sTrimIso = "-north side iso";
1181  break;
1182  default:
1183  sTrimIso = "-unknown_iso_flag";
1184  break;
1185  }
1186  dump.Print("\tedge(%2d) v0(%2d) v1(%2d) tolerance(%g, %g)\n", trim.m_ei, trim.m_vi[0], trim.m_vi[1], trim.m_tolerance[0], trim.m_tolerance[1]);
1187  dump.PushIndent();
1188  dump.Print("\ttype(%s%s) rev3d(%d) 2d_curve(%d)\n", sTrimType, sTrimIso, trim.m_bRev3d, trim.m_c2i);
1189  if (c2) {
1190  trim_start = trim.PointAtStart();
1191  trim_end = trim.PointAtEnd();
1192  dump.Print("\tdomain(%g, %g) start(%g, %g) end(%g, %g)\n", trim.Domain()[0], trim.Domain()[1], trim_start.x, trim_start.y, trim_end.x, trim_end.y);
1193  if (0 != trim_srf) {
1194  ON_3dPoint trim_srfstart = trim_srf->PointAt(trim_start.x, trim_start.y);
1195  ON_3dPoint trim_srfend = trim_srf->PointAt(trim_end.x, trim_end.y);
1196  dump.Print("\tsurface points start(%g, %g, %g) end(%g, %g, %g)\n", trim_srfstart.x, trim_srfstart.y, trim_srfstart.z, trim_srfend.x, trim_srfend.y, trim_srfend.z);
1197  }
1198  } else {
1199  dump.Print("\tdomain(%g, %g) start(?, ?) end(?, ?)\n", trim.Domain()[0], trim.Domain()[1]);
1200  }
1201  dump.PopIndent();
1202  dump.Print("NURBS form of 2d_curve(trim)\n");
1203  nc2->Dump(dump);
1204  delete nc2;
1205 
1206  ON_String ss = wstr;
1207  bu_vls_printf(vls, "%s\n", ss.Array());
1208  return 0;
1209 }
1210 
1211 
1212 int
1213 brep_trim_bezier_info(struct brep_specific* bs, struct bu_vls *vls, int ti)
1214 {
1215  ON_Brep* brep = bs->brep;
1216  ON_wString wstr;
1217  ON_TextLog dump(wstr);
1218  if (brep == NULL) {
1219  return -1;
1220  }
1221  if (!brep->IsValid(&dump)) {
1222  bu_log("brep is NOT valid");
1223  }
1224 
1225  if (!((ti >= 0) && (ti < brep->m_T.Count())))
1226  return 0;
1227  const ON_BrepTrim &trim = brep->m_T[ti];
1228  const ON_Curve* c2 = trim.TrimCurveOf();
1229  ON_NurbsCurve* nc2 = ON_NurbsCurve::New();
1230  c2->GetNurbForm(*nc2, 0.0);
1231  int knotlength = nc2->m_order + nc2->m_cv_count - 2;
1232  int order = nc2->m_order;
1233  fastf_t *knot = nc2->m_knot;
1234  dump.Print("trim[%2d]: domain(%g, %g)\n", ti, nc2->Domain()[0], nc2->Domain()[1]);
1235  int cnt = 0;
1236  dump.Print("NURBS converts to Bezier\n");
1237  for (int i = 0; i < knotlength - 1; ++i) {
1238  ON_BezierCurve* bezier = new ON_BezierCurve;
1239  if (nc2->ConvertSpanToBezier(i, *bezier)) {
1240  dump.Print("NO.%d segment\n", ++cnt);
1241  dump.Print("spanindex from %d to %d\n", i + order - 2, i + order - 1);
1242  dump.Print("knot from %.2f to %.2f\n ", knot[i + order - 2], knot[i + order - 1]);
1243  dump.Print("domain(%g, %g)\n", bezier->Domain()[0], bezier->Domain()[1]);
1244  bezier->Dump(dump);
1245  dump.Print("\n");
1246  }
1247  delete bezier;
1248  }
1249  delete nc2;
1250  ON_String ss = wstr;
1251  bu_vls_printf(vls, "%s\n", ss.Array());
1252  return 0;
1253 }
1254 
1255 
1256 int
1257 brep_curve_info(struct brep_specific* bs, struct bu_vls *vls, int ci)
1258 {
1259  ON_Brep* brep = bs->brep;
1260  ON_wString wstr;
1261  ON_TextLog dump(wstr);
1262  if (brep == NULL) {
1263  return -1;
1264  }
1265  if (!((ci >= 0) && (ci < brep->m_C3.Count())))
1266  return 0;
1267  const ON_Curve *curve = brep->m_C3[ci];
1268  ON_NurbsCurve* nc3 = ON_NurbsCurve::New();
1269  curve->GetNurbForm(*nc3, 0.0);
1270  dump.Print("NURBS form of 3d_curve(edge) \n");
1271  nc3->Dump(dump);
1272  delete nc3;
1273 
1274  ON_String ss = wstr;
1275  bu_vls_printf(vls, "%s\n", ss.Array());
1276  return 0;
1277 }
1278 
1279 int
1280 brep_loop_info(struct brep_specific* bs, struct bu_vls *vls, int li)
1281 {
1282  ON_Brep* brep = bs->brep;
1283  ON_wString wstr;
1284  ON_TextLog dump(wstr);
1285  if (brep == NULL) {
1286  return -1;
1287  }
1288  if (!brep->IsValid(&dump)) {
1289  bu_log("brep is NOT valid");
1290  }
1291 
1292  if (!((li >= 0) && (li < brep->m_L.Count())))
1293  return 0;
1294  const ON_BrepLoop &loop = brep->m_L[li];
1295  dump.Print("loop[%d] on face %d with %d trims\n", li, loop.m_fi, loop.TrimCount());
1296  if (loop.TrimCount() > 0) {
1297  dump.Print("trims: ");
1298  for (int i = 0; i < loop.TrimCount() - 1; ++i) {
1299  dump.Print("%d,", loop.m_ti[i]);
1300  }
1301  dump.Print("%d\n", loop.m_ti[loop.TrimCount() - 1]);
1302  }
1303  ON_String ss = wstr;
1304  bu_vls_printf(vls, "%s\n", ss.Array());
1305  return 0;
1306 }
1307 
1308 int
1309 brep_edge_info(struct brep_specific* bs, struct bu_vls *vls, int ei)
1310 {
1311  ON_Brep* brep = bs->brep;
1312  ON_wString wstr;
1313  ON_TextLog dump(wstr);
1314  if (brep == NULL) {
1315  return -1;
1316  }
1317  if (!brep->IsValid(&dump)) {
1318  bu_log("brep is NOT valid");
1319  }
1320 
1321  if (!((ei >= 0) && (ei < brep->m_E.Count())))
1322  return 0;
1323  const ON_BrepEdge &edge = brep->m_E[ei];
1324  int trim_cnt = edge.m_ti.Count();
1325  const ON_Curve* c3 = edge.EdgeCurveOf();
1326  ON_NurbsCurve* nc3 = ON_NurbsCurve::New();
1327  c3->GetNurbForm(*nc3, 0.0);
1328  ON_3dPoint edge_start, edge_end;
1329  dump.Print("edge[%2d]: for ", ei);
1330  for (int i = 0; i < trim_cnt; ++i) {
1331  dump.Print("trim[%2d] ", edge.m_ti[i]);
1332  }
1333  dump.Print("\n");
1334  dump.Print("v0(%2d) v1(%2d) 3d_curve(%2d) tolerance(%g, %g)\n", ei, edge.m_vi[0], edge.m_vi[1], edge.m_c3i, edge.m_tolerance);
1335  dump.PushIndent();
1336  if (c3) {
1337  edge_start = edge.PointAtStart();
1338  edge_end = edge.PointAtEnd();
1339  dump.Print("\tdomain(%g, %g) surface points start(%g, %g, %g) end(%g, %g, %g)\n", edge.Domain()[0], edge.Domain()[1], edge_start.x, edge_start.y, edge_start.z, edge_end.x, edge_end.y, edge_end.z);
1340  } else {
1341  dump.Print("\tdomain(%g, %g) start(?, ?) end(?, ?)\n", edge.Domain()[0], edge.Domain()[1]);
1342  }
1343  dump.PopIndent();
1344  dump.Print("NURBS form of 3d_curve(edge) \n");
1345  nc3->Dump(dump);
1346  delete nc3;
1347 
1348  ON_String ss = wstr;
1349  bu_vls_printf(vls, "%s\n", ss.Array());
1350  return 0;
1351 }
1352 
1353 
1354 int brep_facecdt_plot(struct bu_vls *vls, const char *solid_name,
1355  const struct rt_tess_tol *ttol, const struct bn_tol *tol,
1356  struct brep_specific* bs, struct rt_brep_internal*UNUSED(bi),
1357  struct bn_vlblock *vbp, int index, int plottype, int num_points = -1)
1358 {
1359  register struct bu_list *vhead = rt_vlblock_find(vbp, YELLOW);
1360  bool watertight = true;
1361  ON_wString wstr;
1362  ON_TextLog tl(wstr);
1363 
1364  ON_Brep* brep = bs->brep;
1365  if (brep == NULL || !brep->IsValid(&tl)) {
1366  if (wstr.Length() > 0) {
1367  ON_String onstr = ON_String(wstr);
1368  const char *isvalidinfo = onstr.Array();
1369  bu_vls_strcat(vls, "brep (");
1370  bu_vls_strcat(vls, solid_name);
1371  bu_vls_strcat(vls, ") is NOT valid:");
1372  bu_vls_strcat(vls, isvalidinfo);
1373  } else {
1374  bu_vls_strcat(vls, "brep (");
1375  bu_vls_strcat(vls, solid_name);
1376  bu_vls_strcat(vls, ") is NOT valid.");
1377  }
1378  //for now try to draw - return -1;
1379  }
1380 
1381  for (int face_index = 0; face_index < brep->m_F.Count(); face_index++) {
1382  ON_BrepFace *face = brep->Face(face_index);
1383  const ON_Surface *s = face->SurfaceOf();
1384  double surface_width, surface_height;
1385  if (s->GetSurfaceSize(&surface_width, &surface_height)) {
1386  // reparameterization of the face's surface and transforms the "u"
1387  // and "v" coordinates of all the face's parameter space trimming
1388  // curves to minimize distortion in the map from parameter space to 3d..
1389  face->SetDomain(0, 0.0, surface_width);
1390  face->SetDomain(1, 0.0, surface_height);
1391  }
1392  }
1393 
1394  if (index == -1) {
1395  for (index = 0; index < brep->m_F.Count(); index++) {
1396  ON_BrepFace& face = brep->m_F[index];
1397  poly2tri_CDT(vhead, face, ttol, tol, NULL, watertight, plottype, num_points);
1398  }
1399  } else if (index < brep->m_F.Count()) {
1400  ON_BrepFaceArray& faces = brep->m_F;
1401  if (index < faces.Count()) {
1402  ON_BrepFace& face = faces[index];
1403  face.Dump(tl);
1404  poly2tri_CDT(vhead, face, ttol, tol, NULL, watertight, plottype, num_points);
1405  }
1406  }
1407 
1408  bu_vls_printf(vls, ON_String(wstr).Array());
1409 
1410  return 0;
1411 }
1412 
1413 
1414 int
1415 brep_facetrim_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, int plotres, bool dim3d)
1416 {
1417  ON_wString wstr;
1418  ON_TextLog tl(wstr);
1419 
1420  ON_Brep* brep = bs->brep;
1421  if (brep == NULL) {
1422  return -1;
1423  }
1424  if (!brep->IsValid(&tl)) {
1425  bu_log("brep is NOT valid");
1426  }
1427 
1428  if (index == -1) {
1429  for (index = 0; index < brep->m_F.Count(); index++) {
1430  ON_BrepFace& face = brep->m_F[index];
1431  if (!dim3d)
1432  plotUVDomain2d(face, vbp);
1433  plottrim(face, vbp, plotres, dim3d);
1434  }
1435  } else if (index < brep->m_F.Count()) {
1436  ON_BrepFaceArray& faces = brep->m_F;
1437  if (index < faces.Count()) {
1438  ON_BrepFace& face = faces[index];
1439  face.Dump(tl);
1440  if (!dim3d)
1441  plotUVDomain2d(face, vbp);
1442  plottrim(face, vbp, plotres, dim3d);
1443  }
1444  }
1445 
1446  bu_vls_printf(vls, ON_String(wstr).Array());
1447  return 0;
1448 }
1449 
1450 
1451 int
1452 brep_trim_direction_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, int plotres)
1453 {
1454  ON_wString wstr;
1455  ON_TextLog tl(wstr);
1456 
1457  ON_Brep* brep = bs->brep;
1458  if (brep == NULL) {
1459  return -1;
1460  }
1461  if (!brep->IsValid(&tl)) {
1462  bu_log("brep is NOT valid");
1463  }
1464 
1465  if (index == -1) {
1466  for (index = 0; index < brep->m_F.Count(); index++) {
1467  ON_BrepFace& face = brep->m_F[index];
1468  plottrimdirection(face, vbp, plotres);
1469  }
1470  } else if (index < brep->m_F.Count()) {
1471  ON_BrepFaceArray& faces = brep->m_F;
1472  if (index < faces.Count()) {
1473  ON_BrepFace& face = faces[index];
1474  face.Dump(tl);
1475  plottrimdirection(face, vbp, plotres);
1476  }
1477  }
1478 
1479  bu_vls_printf(vls, ON_String(wstr).Array());
1480  return 0;
1481 }
1482 
1483 
1484 int
1485 brep_surface_uv_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, double u, double v)
1486 {
1487  ON_wString wstr;
1488  ON_TextLog tl(wstr);
1489 
1490  ON_Brep* brep = bs->brep;
1491  if (brep == NULL) {
1492  return -1;
1493  }
1494  if (!brep->IsValid(&tl)) {
1495  bu_log("brep is NOT valid");
1496  }
1497 
1498  if (index == -1) {
1499  for (index = 0; index < brep->m_S.Count(); index++) {
1500  ON_Surface *surf = brep->m_S[index];
1501  plotpoint(surf->PointAt(u, v), vbp, GREEN);
1502  }
1503  } else if (index < brep->m_S.Count()) {
1504  ON_Surface *surf = brep->m_S[index];
1505  surf->Dump(tl);
1506  plotpoint(surf->PointAt(u, v), vbp, GREEN);
1507  }
1508 
1509  bu_vls_printf(vls, ON_String(wstr).Array());
1510 
1511  return 0;
1512 }
1513 
1514 
1515 int
1516 brep_surface_uv_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, ON_Interval &U, ON_Interval &V)
1517 {
1518  ON_wString wstr;
1519  ON_TextLog tl(wstr);
1520 
1521  ON_Brep* brep = bs->brep;
1522  if (brep == NULL) {
1523  return -1;
1524  }
1525  if (!brep->IsValid(&tl)) {
1526  bu_log("brep is NOT valid");
1527  }
1528 
1529  if ((index >= 0)&&(index < brep->m_S.Count())) {
1530  ON_Surface *surf = brep->m_S[index];
1531  register struct bu_list *vhead;
1532  fastf_t pt1[3], pt2[3];
1533  fastf_t delta = U.Length()/1000.0;
1534 
1535  vhead = rt_vlblock_find(vbp, YELLOW);
1536  for (int i = 0; i < 2; i++) {
1537  fastf_t v = V.m_t[i];
1538  for (fastf_t u = U.m_t[0]; u < U.m_t[1]; u = u + delta) {
1539  ON_3dPoint p = surf->PointAt(u, v);
1540  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y, p.x, p.y, p.z);
1541  VMOVE(pt1, p);
1542  if (u + delta > U.m_t[1]) {
1543  p = surf->PointAt(U.m_t[1], v);
1544  } else {
1545  p = surf->PointAt(u + delta, v);
1546  }
1547  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y+deltay, p.x, p.y, p.z);
1548  VMOVE(pt2, p);
1549  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
1550  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
1551  }
1552  }
1553  delta = V.Length()/1000.0;
1554  for (int i = 0; i < 2; i++) {
1555  fastf_t u = U.m_t[i];
1556  for (fastf_t v = V.m_t[0]; v < V.m_t[1]; v = v + delta) {
1557  ON_3dPoint p = surf->PointAt(u, v);
1558  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y, p.x, p.y, p.z);
1559  VMOVE(pt1, p);
1560  if (v + delta > V.m_t[1]) {
1561  p = surf->PointAt(u,V.m_t[1]);
1562  } else {
1563  p = surf->PointAt(u, v + delta);
1564  }
1565  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y+deltay, p.x, p.y, p.z);
1566  VMOVE(pt2, p);
1567  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
1568  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
1569  }
1570  }
1571  }
1572 
1573  bu_vls_printf(vls, ON_String(wstr).Array());
1574 
1575  return 0;
1576 }
1577 
1578 
1579 int
1580 brep_surface_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, int plotres)
1581 {
1582  ON_wString wstr;
1583  ON_TextLog tl(wstr);
1584 
1585  ON_Brep* brep = bs->brep;
1586  if (brep == NULL) {
1587  return -1;
1588  }
1589  if (!brep->IsValid(&tl)) {
1590  bu_log("brep is NOT valid");
1591  }
1592 
1593  if (index == -1) {
1594  for (index = 0; index < brep->m_S.Count(); index++) {
1595  ON_Surface *surf = brep->m_S[index];
1596  plotsurface(*surf, vbp, plotres, 10);
1597  }
1598  } else if (index < brep->m_S.Count()) {
1599  ON_Surface *surf = brep->m_S[index];
1600  surf->Dump(tl);
1601  plotsurface(*surf, vbp, plotres, 10);
1602  }
1603 
1604  bu_vls_printf(vls, ON_String(wstr).Array());
1605 
1606  return 0;
1607 }
1608 
1609 
1610 int
1611 brep_surface_normal_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, int plotres)
1612 {
1613  ON_wString wstr;
1614  ON_TextLog tl(wstr);
1615 
1616  ON_Brep* brep = bs->brep;
1617  if (brep == NULL) {
1618  return -1;
1619  }
1620  if (!brep->IsValid(&tl)) {
1621  bu_log("brep is NOT valid");
1622  }
1623 
1624  if (index == -1) {
1625  for (index = 0; index < brep->m_S.Count(); index++) {
1626  ON_Surface *surf = brep->m_S[index];
1627  plotsurfaceknots(*surf, vbp, true);
1628  plotsurfacenormals(*surf, vbp, plotres);
1629  }
1630  } else if (index < brep->m_S.Count()) {
1631  ON_Surface *surf = brep->m_S[index];
1632  surf->Dump(tl);
1633  plotsurfaceknots(*surf, vbp, true);
1634  plotsurfacenormals(*surf, vbp, plotres);
1635  }
1636 
1637  bu_vls_printf(vls, ON_String(wstr).Array());
1638  return 0;
1639 }
1640 
1641 
1642 int
1643 brep_surface_knot_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, bool dim3d)
1644 {
1645  ON_wString wstr;
1646  ON_TextLog tl(wstr);
1647 
1648  ON_Brep* brep = bs->brep;
1649  if (brep == NULL) {
1650  return -1;
1651  }
1652  if (!brep->IsValid(&tl)) {
1653  bu_log("brep is NOT valid");
1654  }
1655 
1656  if (index == -1) {
1657  for (index = 0; index < brep->m_S.Count(); index++) {
1658  ON_Surface *surf = brep->m_S[index];
1659  plotsurfaceknots(*surf, vbp, dim3d);
1660  }
1661  } else if (index < brep->m_S.Count()) {
1662  ON_Surface *surf = brep->m_S[index];
1663  surf->Dump(tl);
1664  plotsurfaceknots(*surf, vbp, dim3d);
1665  }
1666 
1667  bu_vls_printf(vls, ON_String(wstr).Array());
1668  return 0;
1669 }
1670 
1671 
1672 int
1673 brep_edge3d_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, int plotres)
1674 {
1675  ON_wString wstr;
1676  ON_TextLog tl(wstr);
1677 
1678  ON_Brep* brep = bs->brep;
1679  if (brep == NULL) {
1680  return -1;
1681  }
1682  if (!brep->IsValid(&tl)) {
1683  bu_log("brep is NOT valid");
1684  }
1685 
1686  if (index == -1) {
1687  int num_curves = brep->m_C3.Count();
1688  for (index = 0; index < num_curves; index++) {
1689  ON_Curve *curve = brep->m_C3[index];
1690  plotcurve(*curve, vbp, plotres);
1691  }
1692  } else if (index < brep->m_C3.Count()) {
1693  ON_Curve *curve = brep->m_C3[index];
1694  curve->Dump(tl);
1695  plotcurve(*curve, vbp, plotres);
1696  }
1697 
1698  bu_vls_printf(vls, ON_String(wstr).Array());
1699  return 0;
1700 }
1701 
1702 
1703 static void
1704 plot_nurbs_cv(struct bn_vlblock *vbp, int ucount, int vcount, ON_NurbsSurface *ns)
1705 {
1706  register struct bu_list *vhead;
1707  vhead = rt_vlblock_find(vbp, PEACH);
1708  ON_3dPoint cp;
1709  fastf_t pt1[3], pt2[3];
1710  int i, j, k, temp;
1711  for (k = 0; k < 2; k++) {
1712  /*< two times i loop */
1713 
1714  for (i = 0; i < ucount; ++i) {
1715  if (k == 1)
1716  ns->GetCV(0, i, cp); /*< i < ucount */
1717  else
1718  ns->GetCV(i, 0, cp); /*< i < vcount */
1719 
1720  VMOVE(pt1, cp);
1721  for (j = 0; j < vcount; ++j) {
1722  if (k == 1)
1723  ns->GetCV(j, i, cp);
1724  else
1725  ns->GetCV(i, j, cp);
1726 
1727  VMOVE(pt2, cp);
1728  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
1729  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
1730  VMOVE(pt1, cp);
1731  RT_ADD_VLIST(vhead, cp, BN_VLIST_POINT_DRAW);
1732  }
1733  }
1734  temp = ucount;
1735  ucount = vcount;
1736  vcount = temp;
1737  }
1738 }
1739 
1740 
1741 int
1742 brep_trim_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, int plotres, bool dim3d)
1743 {
1744  ON_wString wstr;
1745  ON_TextLog tl(wstr);
1746 
1747  ON_Brep* brep = bs->brep;
1748  if (brep == NULL) {
1749  return -1;
1750  }
1751  if (!brep->IsValid(&tl)) {
1752  bu_log("brep is NOT valid");
1753  }
1754 
1755  if (index == -1) {
1756  int num_trims = brep->m_T.Count();
1757  for (index = 0; index < num_trims; index++) {
1758  ON_BrepTrim &trim = brep->m_T[index];
1759  plottrim(trim, vbp, plotres, dim3d);
1760  }
1761  } else if (index < brep->m_T.Count()) {
1762  ON_BrepTrim &trim = brep->m_T[index];
1763  plottrim(trim, vbp, plotres, dim3d);
1764  }
1765 
1766  bu_vls_printf(vls, ON_String(wstr).Array());
1767  return 0;
1768 }
1769 
1770 int
1771 brep_loop_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, int plotres, bool dim3d)
1772 {
1773  ON_wString wstr;
1774  ON_TextLog ll(wstr);
1775 
1776  ON_Brep* brep = bs->brep;
1777  if (brep == NULL) {
1778  return -1;
1779  }
1780  if (!brep->IsValid(&ll)) {
1781  bu_log("brep is NOT valid");
1782  }
1783 
1784  if (index == -1) {
1785  for (int i = 0; i < brep->m_L.Count(); i++) {
1786  ON_BrepLoop* loop = &(brep->m_L[i]);
1787  for (int ti = 0; ti < loop->m_ti.Count(); ti++) {
1788  ON_BrepTrim& trim = brep->m_T[loop->m_ti[ti]];
1789  plottrim(trim, vbp, plotres, dim3d);
1790  }
1791  }
1792  } else if (index < brep->m_L.Count()) {
1793  ON_BrepLoop* loop = &(brep->m_L[index]);
1794  for (int ti = 0; ti < loop->m_ti.Count(); ti++) {
1795  ON_BrepTrim& trim = brep->m_T[loop->m_ti[ti]];
1796  plottrim(trim, vbp, plotres, dim3d);
1797  }
1798  }
1799 
1800  bu_vls_printf(vls, ON_String(wstr).Array());
1801  return 0;
1802 }
1803 
1804 int
1805 brep_surface_cv_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index)
1806 {
1807  ON_wString wstr;
1808  ON_TextLog tl(wstr);
1809 
1810  ON_Brep* brep = bs->brep;
1811  if (brep == NULL) {
1812  return -1;
1813  }
1814  if (!brep->IsValid(&tl)) {
1815  bu_log("brep is NOT valid");
1816  }
1817 
1818  if (index == -1) {
1819  for (index = 0; index < brep->m_S.Count(); index++) {
1820  ON_Surface *surf = brep->m_S[index];
1821  ON_NurbsSurface *ns = ON_NurbsSurface::New();
1822  surf->GetNurbForm(*ns, 0.0);
1823  int ucount, vcount;
1824  ucount = ns->m_cv_count[0];
1825  vcount = ns->m_cv_count[1];
1826  surf->Dump(tl);
1827  plot_nurbs_cv(vbp, ucount, vcount, ns);
1828  }
1829  } else if (index < brep->m_S.Count()) {
1830  ON_Surface *surf = brep->m_S[index];
1831  ON_NurbsSurface *ns = ON_NurbsSurface::New();
1832  surf->GetNurbForm(*ns, 0.0);
1833  int ucount, vcount;
1834  ucount = ns->m_cv_count[0];
1835  vcount = ns->m_cv_count[1];
1836  plot_nurbs_cv(vbp, ucount, vcount, ns);
1837  }
1838  bu_vls_printf(vls, ON_String(wstr).Array());
1839  return 0;
1840 
1841 }
1842 
1843 
1844 /* a binary predicate for std:list implemented as a function */
1845 extern bool near_equal (double first, double second);
1846 
1847 
1848 void
1849 plotFace(SurfaceTree* st, struct bn_vlblock *vbp, int UNUSED(isocurveres), int gridres)
1850 {
1851  register struct bu_list *vhead;
1852  fastf_t pt1[3], pt2[3];
1853  ON_2dPoint from, to;
1854  std::list<BRNode*> m_trims_above_or_right;
1855  std::list<fastf_t> trim_hits;
1856 
1857  vhead = rt_vlblock_find(vbp, PEACH);
1858 
1859  const ON_Surface *surf = st->getSurface();
1860  CurveTree *ctree = st->ctree;
1861  ON_Interval udom = surf->Domain(0);
1862  ON_Interval vdom = surf->Domain(1);
1863  //bu_log("udom %f, %f vdom %f, %f\n", udom.m_t[0], udom.m_t[1], vdom.m_t[0], vdom.m_t[1]);
1864 
1865  m_trims_above_or_right.clear();
1866 
1867  ON_2dPoint pt;
1868  for (int gd = 1; gd < gridres; gd++) {
1869 
1870  pt.x = udom.ParameterAt((double)gd /(double)gridres);
1871  pt.y = vdom.ParameterAt(0.0);
1872 
1873  if (ctree != NULL) {
1874  m_trims_above_or_right.clear();
1875  ctree->getLeavesAbove(m_trims_above_or_right, pt, 0.0000001);
1876  }
1877  int cnt=1;
1878  //bu_log("U - %f\n", pt.x);
1879  trim_hits.clear();
1880  for (std::list<BRNode*>::iterator i = m_trims_above_or_right.begin(); i != m_trims_above_or_right.end(); i++, cnt++) {
1881  BRNode* br = dynamic_cast<BRNode*>(*i);
1882 
1883  point_t bmin, bmax;
1884  br->GetBBox(bmin, bmax);
1885  if ((bmin[X] <= pt[X]) && (pt[X] <= bmax[X])) { //if check trim and in BBox
1886  fastf_t v = br->getCurveEstimateOfV(pt[X], 0.0000001);
1887  trim_hits.push_back(v);
1888  //bu_log("%d V %d - %f pt %f, %f bmin %f, %f bmax %f, %f\n", br->m_face->m_face_index, cnt, v, pt.x, pt.y, bmin[X], bmin[Y], bmax[X], bmax[Y]);
1889  }
1890  }
1891  trim_hits.sort();
1892  trim_hits.unique(near_equal);
1893 
1894  size_t hit_cnt = trim_hits.size();
1895 
1896  if ((hit_cnt > 1) && ((hit_cnt % 2) == 0)) {
1897  //bu_log("U - %f\n", pt.x);
1898  while (!trim_hits.empty()) {
1899  fastf_t tfrom = trim_hits.front();
1900  trim_hits.pop_front();
1901  fastf_t tto = trim_hits.front();
1902  trim_hits.pop_front();
1903  //bu_log("\tfrom - %f, to - %f\n", tfrom, tto);
1904  fastf_t deltay = (tto-tfrom)/50.0;
1905  for (fastf_t y = tfrom; y < tto - deltay; y = y + deltay) {
1906  ON_3dPoint p = surf->PointAt(pt.x, y);
1907  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y, p.x, p.y, p.z);
1908  VMOVE(pt1, p);
1909  p = surf->PointAt(pt.x, y+deltay);
1910  if (y+deltay > tto) {
1911  p = surf->PointAt(pt.x, tto);
1912  } else {
1913  p = surf->PointAt(pt.x, y+deltay);
1914  }
1915  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y+deltay, p.x, p.y, p.z);
1916  VMOVE(pt2, p);
1917  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
1918  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
1919  }
1920 
1921  }
1922  }
1923  // v direction
1924  pt.x = udom.ParameterAt(0.0);
1925  pt.y = vdom.ParameterAt((double)gd /(double)gridres);
1926 
1927  if (ctree != NULL) {
1928  m_trims_above_or_right.clear();
1929  ctree->getLeavesRight(m_trims_above_or_right, pt, 0.0000001);
1930  }
1931 
1932  cnt=1;
1933  //bu_log("V - %f\n", pt.x);
1934  trim_hits.clear();
1935  for (std::list<BRNode*>::iterator i = m_trims_above_or_right.begin(); i != m_trims_above_or_right.end(); i++, cnt++) {
1936  BRNode* br = dynamic_cast<BRNode*>(*i);
1937 
1938  point_t bmin, bmax;
1939  br->GetBBox(bmin, bmax);
1940  if ((bmin[Y] <= pt[Y]) && (pt[Y] <= bmax[Y])) { //if check trim and in BBox
1941  fastf_t u = br->getCurveEstimateOfU(pt[Y], 0.0000001);
1942  trim_hits.push_back(u);
1943  //bu_log("%d U %d - %f pt %f, %f bmin %f, %f bmax %f, %f\n", br->m_face->m_face_index, cnt, u, pt.x, pt.y, bmin[X], bmin[Y], bmax[X], bmax[Y]);
1944  }
1945  }
1946  trim_hits.sort();
1947  trim_hits.unique(near_equal);
1948 
1949  hit_cnt = trim_hits.size();
1950 
1951  if ((hit_cnt > 1) && ((hit_cnt % 2) == 0)) {
1952  //bu_log("V - %f\n", pt.y);
1953  while (!trim_hits.empty()) {
1954  fastf_t tfrom = trim_hits.front();
1955  trim_hits.pop_front();
1956  fastf_t tto = trim_hits.front();
1957  trim_hits.pop_front();
1958  //bu_log("\tfrom - %f, to - %f\n", tfrom, tto);
1959  fastf_t deltax = (tto-tfrom)/50.0;
1960  for (fastf_t x = tfrom; x < tto; x = x + deltax) {
1961  ON_3dPoint p = surf->PointAt(x, pt.y);
1962  VMOVE(pt1, p);
1963  if (x+deltax > tto) {
1964  p = surf->PointAt(tto, pt.y);
1965  } else {
1966  p = surf->PointAt(x+deltax, pt.y);
1967  }
1968  VMOVE(pt2, p);
1969  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
1970  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
1971  }
1972 
1973  }
1974  }
1975 
1976  }
1977 
1978  return;
1979 }
1980 
1981 
1982 void
1983 drawisoUCheckForTrim(SurfaceTree* st, struct bn_vlblock *vbp, fastf_t from, fastf_t to, fastf_t v, int UNUSED(curveres))
1984 {
1985  register struct bu_list *vhead;
1986  fastf_t pt1[3], pt2[3];
1987  std::list<BRNode*> m_trims_right;
1988  std::list<fastf_t> trim_hits;
1989 
1990  vhead = rt_vlblock_find(vbp, YELLOW);
1991 
1992  const ON_Surface *surf = st->getSurface();
1993  CurveTree *ctree = st->ctree;
1994  fastf_t umin, umax;
1995  surf->GetDomain(0, &umin, &umax);
1996 
1997  m_trims_right.clear();
1998 
1999  fastf_t tol = 0.001;
2000  ON_2dPoint pt;
2001  pt.x = umin;
2002  pt.y = v;
2003 
2004  if (ctree != NULL) {
2005  m_trims_right.clear();
2006  ctree->getLeavesRight(m_trims_right, pt, tol);
2007  }
2008 
2009  int cnt = 1;
2010  //bu_log("V - %f\n", pt.x);
2011  trim_hits.clear();
2012  for (std::list<BRNode*>::iterator i = m_trims_right.begin(); i != m_trims_right.end(); i++, cnt++) {
2013  BRNode* br = dynamic_cast<BRNode*> (*i);
2014 
2015  point_t bmin, bmax;
2016  if (!br->m_Horizontal) {
2017  br->GetBBox(bmin, bmax);
2018  if (((bmin[Y] - tol) <= pt[Y]) && (pt[Y] <= (bmax[Y]+tol))) { //if check trim and in BBox
2019  fastf_t u = br->getCurveEstimateOfU(pt[Y], tol);
2020  trim_hits.push_back(u);
2021  //bu_log("%d U %d - %f pt %f, %f bmin %f, %f bmax %f, %f\n", br->m_face->m_face_index, cnt, u, pt.x, pt.y, bmin[X], bmin[Y], bmax[X], bmax[Y]);
2022  }
2023  }
2024  }
2025  trim_hits.sort();
2026  trim_hits.unique(near_equal);
2027 
2028  int hit_cnt = trim_hits.size();
2029  cnt = 1;
2030  //bu_log("\tdrawisoUCheckForTrim: hit_cnt %d from center %f %f 0.0 to center %f %f 0.0\n", hit_cnt, from, v , to, v);
2031 
2032  if ((hit_cnt > 0) && ((hit_cnt % 2) == 0)) {
2033 /*
2034  if ((hit_cnt % 2) != 0) {
2035  //bu_log("V - %f\n", pt.y);
2036  if (!trim_hits.empty()) {
2037  fastf_t end = trim_hits.front();
2038  trim_hits.pop_front();
2039  //bu_log("\tfrom - %f, to - %f\n", from, to);
2040  fastf_t deltax = (end - from) / 50.0;
2041  if (deltax > 0.001) {
2042  for (fastf_t x = from; x < end && x < to; x = x + deltax) {
2043  ON_3dPoint p = surf->PointAt(x, pt.y);
2044  VMOVE(pt1, p);
2045  if (x + deltax > end) {
2046  if (x + deltax > to) {
2047  p = surf->PointAt(to, pt.y);
2048  } else {
2049  p = surf->PointAt(end, pt.y);
2050  }
2051  } else {
2052  if (x + deltax > to) {
2053  p = surf->PointAt(to, pt.y);
2054  } else {
2055  p = surf->PointAt(x + deltax, pt.y);
2056  }
2057  }
2058  VMOVE(pt2, p);
2059 
2060  //bu_log(
2061  // "\t\t%d from center %f %f 0.0 to center %f %f 0.0\n",
2062  // cnt++, x, v, x + deltax, v);
2063 
2064  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
2065  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
2066  }
2067  }
2068  }
2069  }
2070 */
2071  while (!trim_hits.empty()) {
2072  fastf_t start = trim_hits.front();
2073  if (start < from) {
2074  start = from;
2075  }
2076  trim_hits.pop_front();
2077  fastf_t end = trim_hits.front();
2078  if (end > to) {
2079  end = to;
2080  }
2081  trim_hits.pop_front();
2082  //bu_log("\tfrom - %f, to - %f\n", from, to);
2083  fastf_t deltax = (end - start) / 50.0;
2084  if (deltax > 0.001) {
2085  for (fastf_t x = start; x < end; x = x + deltax) {
2086  ON_3dPoint p = surf->PointAt(x, pt.y);
2087  VMOVE(pt1, p);
2088  if (x + deltax > end) {
2089  p = surf->PointAt(end, pt.y);
2090  } else {
2091  p = surf->PointAt(x + deltax, pt.y);
2092  }
2093  VMOVE(pt2, p);
2094 
2095  // bu_log(
2096  // "\t\t%d from center %f %f 0.0 to center %f %f 0.0\n",
2097  // cnt++, x, v, x + deltax, v);
2098 
2099  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
2100  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
2101  }
2102  }
2103  }
2104  }
2105 
2106  return;
2107 }
2108 
2109 
2110 void
2111 drawisoVCheckForTrim(SurfaceTree* st, struct bn_vlblock *vbp, fastf_t from, fastf_t to, fastf_t u, int UNUSED(curveres))
2112 {
2113  register struct bu_list *vhead;
2114  fastf_t pt1[3], pt2[3];
2115  std::list<BRNode*> m_trims_above;
2116  std::list<fastf_t> trim_hits;
2117 
2118  vhead = rt_vlblock_find(vbp, YELLOW);
2119 
2120  const ON_Surface *surf = st->getSurface();
2121  CurveTree *ctree = st->ctree;
2122  fastf_t vmin, vmax;
2123  surf->GetDomain(1, &vmin, &vmax);
2124 
2125  m_trims_above.clear();
2126 
2127  fastf_t tol = 0.001;
2128  ON_2dPoint pt;
2129  pt.x = u;
2130  pt.y = vmin;
2131 
2132  if (ctree != NULL) {
2133  m_trims_above.clear();
2134  ctree->getLeavesAbove(m_trims_above, pt, tol);
2135  }
2136 
2137  int cnt = 1;
2138  trim_hits.clear();
2139  for (std::list<BRNode*>::iterator i = m_trims_above.begin(); i != m_trims_above.end(); i++, cnt++) {
2140  BRNode* br = dynamic_cast<BRNode*>(*i);
2141 
2142  point_t bmin, bmax;
2143  if (!br->m_Vertical) {
2144  br->GetBBox(bmin, bmax);
2145 
2146  if (((bmin[X] - tol) <= pt[X]) && (pt[X] <= (bmax[X]+tol))) { //if check trim and in BBox
2147  fastf_t v = br->getCurveEstimateOfV(pt[X], tol);
2148  trim_hits.push_back(v);
2149  //bu_log("%d V %d - %f pt %f, %f bmin %f, %f bmax %f, %f\n", br->m_face->m_face_index, cnt, v, pt.x, pt.y, bmin[X], bmin[Y], bmax[X], bmax[Y]);
2150  }
2151  }
2152  }
2153  trim_hits.sort();
2154  trim_hits.unique(near_equal);
2155 
2156  size_t hit_cnt = trim_hits.size();
2157  cnt = 1;
2158 
2159  //bu_log("\tdrawisoVCheckForTrim: hit_cnt %d from center %f %f 0.0 to center %f %f 0.0\n", hit_cnt, u, from, u, to);
2160 
2161  if ((hit_cnt > 0) && ((hit_cnt % 2) == 0)) {
2162 /*
2163  if ((hit_cnt % 2) != 0) { //odd starting inside
2164  //bu_log("V - %f\n", pt.y);
2165  if (!trim_hits.empty()) {
2166  fastf_t end = trim_hits.front();
2167  trim_hits.pop_front();
2168  //bu_log("\tfrom - %f, to - %f\n", from, to);
2169  fastf_t deltay = (end - from) / 50.0;
2170  if (deltay > 0.001) {
2171  for (fastf_t y = from; y < end && y < to; y = y + deltay) {
2172  ON_3dPoint p = surf->PointAt(pt.x, y);
2173  VMOVE(pt1, p);
2174  if (y + deltay > end) {
2175  if (y + deltay > to) {
2176  p = surf->PointAt(pt.x, to);
2177  } else {
2178  p = surf->PointAt(pt.x, end);
2179  }
2180  } else {
2181  if (y + deltay > to) {
2182  p = surf->PointAt(pt.x, to);
2183  } else {
2184  p = surf->PointAt(pt.x, y + deltay);
2185  }
2186  }
2187  VMOVE(pt2, p);
2188 
2189  //bu_log(
2190  // "\t\t%d from center %f %f 0.0 to center %f %f 0.0\n",
2191  // cnt++, u, y, u, y + deltay);
2192 
2193  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
2194  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
2195  }
2196  }
2197 
2198  }
2199  }
2200 */
2201  while (!trim_hits.empty()) {
2202  fastf_t start = trim_hits.front();
2203  trim_hits.pop_front();
2204  if (start < from) {
2205  start = from;
2206  }
2207  fastf_t end = trim_hits.front();
2208  trim_hits.pop_front();
2209  if (end > to) {
2210  end = to;
2211  }
2212  //bu_log("\tfrom - %f, to - %f\n", from, to);
2213  fastf_t deltay = (end - start) / 50.0;
2214  if (deltay > 0.001) {
2215  for (fastf_t y = start; y < end; y = y + deltay) {
2216  ON_3dPoint p = surf->PointAt(pt.x, y);
2217  VMOVE(pt1, p);
2218  if (y + deltay > end) {
2219  p = surf->PointAt(pt.x, end);
2220  } else {
2221  p = surf->PointAt(pt.x, y + deltay);
2222  }
2223  VMOVE(pt2, p);
2224 
2225  //bu_log("\t\t%d from center %f %f 0.0 to center %f %f 0.0\n",
2226  // cnt++, u, y, u, y + deltay);
2227 
2228  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
2229  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
2230  }
2231  }
2232  }
2233  }
2234  return;
2235 }
2236 
2237 
2238 void
2239 drawisoU(SurfaceTree* st, struct bn_vlblock *vbp, fastf_t from, fastf_t to, fastf_t v, int curveres)
2240 {
2241  register struct bu_list *vhead;
2242  fastf_t pt1[3], pt2[3];
2243  fastf_t deltau = (to - from) / curveres;
2244  const ON_Surface *surf = st->getSurface();
2245 
2246  vhead = rt_vlblock_find(vbp, YELLOW);
2247  for (fastf_t u = from; u < to; u = u + deltau) {
2248  ON_3dPoint p = surf->PointAt(u, v);
2249  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y, p.x, p.y, p.z);
2250  VMOVE(pt1, p);
2251  if (u + deltau > to) {
2252  p = surf->PointAt(to, v);
2253  } else {
2254  p = surf->PointAt(u + deltau, v);
2255  }
2256  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y+deltay, p.x, p.y, p.z);
2257  VMOVE(pt2, p);
2258  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
2259  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
2260  }
2261 }
2262 
2263 
2264 void
2265 drawisoV(SurfaceTree* st, struct bn_vlblock *vbp, fastf_t from, fastf_t to, fastf_t u, int curveres)
2266 {
2267  register struct bu_list *vhead;
2268  fastf_t pt1[3], pt2[3];
2269  fastf_t deltav = (to - from) / curveres;
2270  const ON_Surface *surf = st->getSurface();
2271 
2272  vhead = rt_vlblock_find(vbp, YELLOW);
2273  for (fastf_t v = from; v < to; v = v + deltav) {
2274  ON_3dPoint p = surf->PointAt(u, v);
2275  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y, p.x, p.y, p.z);
2276  VMOVE(pt1, p);
2277  if (v + deltav > to) {
2278  p = surf->PointAt(u, to);
2279  } else {
2280  p = surf->PointAt(u, v + deltav);
2281  }
2282  //bu_log("p1 2d - %f, %f 3d - %f, %f, %f\n", pt.x, y+deltay, p.x, p.y, p.z);
2283  VMOVE(pt2, p);
2284  RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
2285  RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
2286  }
2287 }
2288 
2289 
2290 void
2291 drawBBNode(SurfaceTree* st, struct bn_vlblock *vbp, BBNode * node) {
2292  if (node->isLeaf()) {
2293  //draw leaf
2294  if (node->m_trimmed) {
2295  return; // nothing to do node is trimmed
2296  } else if (node->m_checkTrim) { // node may contain trim check all corners
2297  fastf_t u = node->m_u[0];
2298  fastf_t v = node->m_v[0];
2299  fastf_t from = u;
2300  fastf_t to = node->m_u[1];
2301  //bu_log("drawBBNode: node %x uvmin center %f %f 0.0, uvmax center %f %f 0.0\n", node, node->m_u[0], node->m_v[0], node->m_u[1], node->m_v[1]);
2302 
2303  drawisoUCheckForTrim(st, vbp, from, to, v, 3); //bottom
2304  v = node->m_v[1];
2305  drawisoUCheckForTrim(st, vbp, from, to, v, 3); //top
2306  from = node->m_v[0];
2307  to = node->m_v[1];
2308  drawisoVCheckForTrim(st, vbp, from, to, u, 3); //left
2309  u = node->m_u[1];
2310  drawisoVCheckForTrim(st, vbp, from, to, u, 3); //right
2311 
2312  return;
2313  } else { // fully untrimmed just draw bottom and right edges
2314  fastf_t u = node->m_u[0];
2315  fastf_t v = node->m_v[0];
2316  fastf_t from = u;
2317  fastf_t to = node->m_u[1];
2318  drawisoU(st, vbp, from, to, v, 10); //bottom
2319  from = v;
2320  to = node->m_v[1];
2321  drawisoV(st, vbp, from, to, u, 10); //right
2322  return;
2323  }
2324  } else {
2325  if (node->m_children.size() > 0) {
2326  for (std::vector<BBNode*>::iterator childnode = node->m_children.begin(); childnode
2327  != node->m_children.end(); childnode++) {
2328  drawBBNode(st, vbp, *childnode);
2329  }
2330  }
2331  }
2332 }
2333 
2334 
2335 void
2336 plotFaceFromSurfaceTree(SurfaceTree* st, struct bn_vlblock *vbp, int UNUSED(isocurveres), int UNUSED(gridres)) {
2337  BBNode *root = st->getRootNode();
2338  drawBBNode(st, vbp, root);
2339 }
2340 
2341 
2342 int
2343 brep_isosurface_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, int index, int plotres)
2344 {
2345  ON_wString wstr;
2346  ON_TextLog tl(wstr);
2347 
2348  ON_Brep* brep = bs->brep;
2349  if (brep == NULL) {
2350  return -1;
2351  }
2352  if (!brep->IsValid(&tl)) {
2353  bu_log("brep is NOT valid");
2354  }
2355  if (index == -1) {
2356  for (index = 0; index < brep->m_F.Count(); index++) {
2357  ON_BrepFace& face = brep->m_F[index];
2358  SurfaceTree* st = new SurfaceTree(&face, true, 0);
2359  plottrim(face, vbp, plotres, true);
2360  plotFaceFromSurfaceTree(st, vbp, plotres, plotres);
2361  delete st;
2362  }
2363  } else if (index < brep->m_F.Count()) {
2364  ON_BrepFaceArray& faces = brep->m_F;
2365  if (index < faces.Count()) {
2366  ON_BrepFace& face = faces[index];
2367  SurfaceTree* st = new SurfaceTree(&face, true, 0);
2368  plottrim(face, vbp, plotres, true);
2369  plotFaceFromSurfaceTree(st, vbp, plotres, plotres);
2370  delete st;
2371  }
2372  }
2373 
2374  bu_vls_printf(vls, ON_String(wstr).Array());
2375  return 0;
2376 }
2377 
2378 
2379 int
2380 brep_surfaceleafs_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, bool dim3d, int index, int)
2381 {
2382  ON_wString wstr;
2383  ON_TextLog tl(wstr);
2384 
2385  ON_Brep* brep = bs->brep;
2386  if (brep == NULL) {
2387  return -1;
2388  }
2389  if (!brep->IsValid(&tl)) {
2390  bu_log("brep is NOT valid");
2391  }
2392 
2393  if (index == -1) {
2394  for (index = 0; index < brep->m_F.Count(); index++) {
2395  ON_BrepFace& face = brep->m_F[index];
2396  const ON_Surface *s = face.SurfaceOf();
2397  double surface_width,surface_height;
2398  if (s->GetSurfaceSize(&surface_width,&surface_height)) {
2399  // reparameterization of the face's surface and transforms the "u"
2400  // and "v" coordinates of all the face's parameter space trimming
2401  // curves to minimize distortion in the map from parameter space to 3d..
2402  face.SetDomain(0, 0.0, surface_width);
2403  face.SetDomain(1, 0.0, surface_height);
2404  }
2405  SurfaceTree* st = new SurfaceTree(&face);
2406  bu_log("Face: %d contains %d SBBs",index,plotsurfaceleafs(st, vbp, dim3d));
2407  }
2408  } else if (index < brep->m_F.Count()) {
2409  ON_BrepFaceArray& faces = brep->m_F;
2410  if (index < faces.Count()) {
2411  ON_BrepFace& face = faces[index];
2412  const ON_Surface *s = face.SurfaceOf();
2413  double surface_width,surface_height;
2414  if (s->GetSurfaceSize(&surface_width,&surface_height)) {
2415  // reparameterization of the face's surface and transforms the "u"
2416  // and "v" coordinates of all the face's parameter space trimming
2417  // curves to minimize distortion in the map from parameter space to 3d..
2418  face.SetDomain(0, 0.0, surface_width);
2419  face.SetDomain(1, 0.0, surface_height);
2420  }
2421  SurfaceTree* st = new SurfaceTree(&face);
2422  bu_log("Face: %d contains %d SBBs",index,plotsurfaceleafs(st, vbp, dim3d));
2423  }
2424  }
2425 
2426  bu_vls_printf(vls, ON_String(wstr).Array());
2427  return 0;
2428 }
2429 
2430 
2431 int
2432 brep_trimleafs_plot(struct bu_vls *vls, struct brep_specific* bs, struct rt_brep_internal*, struct bn_vlblock *vbp, bool dim3d, int index, int)
2433 {
2434  ON_wString wstr;
2435  ON_TextLog tl(wstr);
2436 
2437  ON_Brep* brep = bs->brep;
2438  if (brep == NULL) {
2439  return -1;
2440  }
2441  if (!brep->IsValid(&tl)) {
2442  bu_log("brep is NOT valid");
2443  }
2444 
2445  if (index == -1) {
2446  for (index = 0; index < brep->m_F.Count(); index++) {
2447  ON_BrepFace& face = brep->m_F[index];
2448  SurfaceTree* st = new SurfaceTree(&face);
2449  plottrimleafs(st, vbp, dim3d);
2450  }
2451  } else if (index < brep->m_F.Count()) {
2452  ON_BrepFaceArray& faces = brep->m_F;
2453  if (index < faces.Count()) {
2454  ON_BrepFace& face = faces[index];
2455  SurfaceTree* st = new SurfaceTree(&face);
2456  plottrimleafs(st, vbp, dim3d);
2457  }
2458  }
2459 
2460  bu_vls_printf(vls, ON_String(wstr).Array());
2461  return 0;
2462 }
2463 
2464 
2465 void
2466 info_usage(struct bu_vls *vls)
2467 {
2468  bu_vls_printf(vls, "mged>brep brepname.s info\n");
2469  bu_vls_printf(vls, "\tinfo - return count information for specific BREP\n");
2470  bu_vls_printf(vls, "\tinfo C [index] or C [index-index] - return information for specific BREP '3D curve'\n");
2471  bu_vls_printf(vls, "\tinfo S [index] or S [index-index] - return information for specific BREP 'surface'\n");
2472  bu_vls_printf(vls, "\tinfo F [index] or F [index-index]- return information for specific BREP 'face'\n");
2473  bu_vls_printf(vls, "\tinfo T [index] or T [index-index]- return information for specific BREP 'trim'\n");
2474  bu_vls_printf(vls, "\tinfo L [index] or L [index-index]- return information for specific BREP 'loop'\n");
2475  bu_vls_printf(vls, "\tinfo E [index] or E [index-index]- return information for specific BREP 'edge'\n");
2476  bu_vls_printf(vls, "\tinfo TB [index] or TB [index-index]- return information for specific BREP 'piecewise bezier trim'\n");
2477  bu_vls_printf(vls, "\tinfo SB [index] or SB [index-index]- return information for specific BREP 'piecewise bezier surface'\n");
2478 }
2479 
2480 
2481 void
2482 plot_usage(struct bu_vls *vls)
2483 {
2484  bu_vls_printf(vls, "mged>brep brepname.s plot\n");
2485  bu_vls_printf(vls, "\tplot - plot entire BREP\n");
2486  bu_vls_printf(vls, "\tplot S [index] or S [index-index]- plot specific BREP 'surface'\n");
2487  bu_vls_printf(vls, "\tplot Suv index[-index] u v- plot specific BREP 'surface' 3d point at specified uv\n");
2488  bu_vls_printf(vls, "\tplot UV index[-index] u1 u2 v1 v2 - plot specific BREP 'surface' 3d bounds at specified uv bounds\n");
2489  bu_vls_printf(vls, "\tplot F [index] or F [index-index]- plot specific BREP 'face'\n");
2490  bu_vls_printf(vls, "\tplot I [index] or I [index-index]- plot specific BREP 'isosurface'\n");
2491  bu_vls_printf(vls, "\tplot SN [index] or SN [index-index]- plot specific BREP 'surface normal'\n");
2492  bu_vls_printf(vls, "\tplot KN [index] or KN [index-index]- plot specific BREP 'surface knot'\n");
2493  bu_vls_printf(vls, "\tplot F2d [index] or F2d [index-index]- plot specific BREP 'face in 2d'\n");
2494  bu_vls_printf(vls, "\tplot SBB [index] or SBB [index-index]- plot specific BREP 'surfaceleafs'\n");
2495  bu_vls_printf(vls, "\tplot SBB2d [index] or SBB2d [index-index]- plot specific BREP 'surfaceleafs in 2d'\n");
2496  bu_vls_printf(vls, "\tplot TD [index] or TD [index-index]- plot specific BREP 'trim direction'\n");
2497  bu_vls_printf(vls, "\tplot T [index] or T [index-index]- plot specific BREP 'trim'\n");
2498  bu_vls_printf(vls, "\tplot T2d [index] or T2d [index-index]- plot specific BREP 'trim in 2d'\n");
2499  bu_vls_printf(vls, "\tplot TBB [index] or TBB [index-index]- plot specific BREP 'trimleafs'\n");
2500  bu_vls_printf(vls, "\tplot TBB2d [index] or TBB2d [index-index]- plot specific BREP 'trimleafs in 2d'\n");
2501  bu_vls_printf(vls, "\tplot E [index] or E [index-index]- plot specific BREP 'edge3d'\n");
2502  bu_vls_printf(vls, "\tplot L [index] or L [index-index]- plot specific BREP 'loop'\n");
2503  bu_vls_printf(vls, "\tplot L2d [index] or L2d [index-index]- plot specific BREP 'loops in 2d'\n");
2504  bu_vls_printf(vls, "\tplot SCV [index] or SCV [index-index]- plot specific BREP 'nurbs control net'\n");
2505 }
2506 
2507 
2508 int
2509 single_conversion(struct rt_db_internal* intern, ON_Brep** brep, const struct db_i* dbip)
2510 {
2511  struct bn_tol tol;
2512  tol.magic = BN_TOL_MAGIC;
2513  tol.dist = BN_TOL_DIST;
2514  tol.dist_sq = tol.dist * tol.dist;
2515  tol.perp = SMALL_FASTF;
2516  tol.para = 1.0 - tol.perp;
2517 
2518  if (intern->idb_type == ID_BREP) {
2519  // already a brep
2520  RT_BREP_CK_MAGIC(intern->idb_ptr);
2521  **brep = *((struct rt_brep_internal *)intern->idb_ptr)->brep;
2522  } else if (intern->idb_type == ID_COMBINATION) {
2523  rt_comb_brep(brep, intern, &tol, dbip);
2524  } else if (intern->idb_meth->ft_brep != NULL) {
2525  intern->idb_meth->ft_brep(brep, intern, &tol);
2526  } else {
2527  *brep = NULL;
2528  return -1;
2529  }
2530  if (*brep == NULL) {
2531  return -2;
2532  }
2533  return 0;
2534 }
2535 
2536 
2537 int
2538 brep_conversion(struct rt_db_internal* in, struct rt_db_internal* out, const struct db_i *dbip)
2539 {
2540  if (out == NULL)
2541  return -1;
2542 
2543  ON_Brep *brep, *old;
2544  old = brep = ON_Brep::New();
2545 
2546  int ret;
2547  if ((ret = single_conversion(in, &brep, dbip)) < 0) {
2548  delete old;
2549  return ret;
2550  }
2551 
2552  struct rt_brep_internal *bip_out;
2553  BU_ALLOC(bip_out, struct rt_brep_internal);
2554  bip_out->magic = RT_BREP_INTERNAL_MAGIC;
2555  bip_out->brep = brep;
2556  RT_DB_INTERNAL_INIT(out);
2557  out->idb_ptr = (void *)bip_out;
2558  out->idb_major_type = DB5_MAJORTYPE_BRLCAD;
2559  out->idb_meth = &OBJ[ID_BREP];
2560  out->idb_minor_type = ID_BREP;
2561 
2562  return 0;
2563 }
2564 
2565 
2566 int
2567 brep_conversion_tree(const struct db_i *dbip, const union tree *oldtree, union tree *newtree, const char *suffix, struct rt_wdb *wdbp, fastf_t local2mm)
2568 {
2569  int ret = 0;
2570  *newtree = *oldtree;
2571  rt_comb_internal *comb = NULL;
2572  switch (oldtree->tr_op) {
2573  case OP_UNION:
2574  case OP_INTERSECT:
2575  case OP_SUBTRACT:
2576  case OP_XOR:
2577  /* convert right */
2578  comb = new rt_comb_internal;
2579  newtree->tr_b.tb_right = new tree;
2580  RT_TREE_INIT(newtree->tr_b.tb_right);
2581  ret = brep_conversion_tree(dbip, oldtree->tr_b.tb_right, newtree->tr_b.tb_right, suffix, wdbp, local2mm);
2582  if (ret) {
2583  delete newtree->tr_b.tb_right;
2584  break;
2585  }
2586  /* fall through */
2587  case OP_NOT:
2588  case OP_GUARD:
2589  case OP_XNOP:
2590  /* convert left */
2591  BU_ALLOC(newtree->tr_b.tb_left, union tree);
2592  RT_TREE_INIT(newtree->tr_b.tb_left);
2593  ret = brep_conversion_tree(dbip, oldtree->tr_b.tb_left, newtree->tr_b.tb_left, suffix, wdbp, local2mm);
2594  if (!ret) {
2595  comb->tree = newtree;
2596  } else {
2597  delete newtree->tr_b.tb_left;
2598  delete newtree->tr_b.tb_right;
2599  }
2600  break;
2601  case OP_DB_LEAF:
2602  char *tmpname;
2603  char *oldname;
2604  oldname = oldtree->tr_l.tl_name;
2605  tmpname = (char*)bu_malloc(strlen(oldname)+strlen(suffix)+1, "char");
2606  newtree->tr_l.tl_name = (char*)bu_malloc(strlen(oldname)+strlen(suffix)+1, "char");
2607  bu_strlcpy(tmpname, oldname, strlen(oldname)+1);
2608  bu_strlcat(tmpname, suffix, strlen(oldname)+strlen(suffix)+1);
2609  if (db_lookup(dbip, tmpname, LOOKUP_QUIET) == RT_DIR_NULL) {
2610  directory *dir;
2611  dir = db_lookup(dbip, oldname, LOOKUP_QUIET);
2612  if (dir != RT_DIR_NULL) {
2613  rt_db_internal *intern;
2614  BU_ALLOC(intern, struct rt_db_internal);
2615  rt_db_get_internal(intern, dir, dbip, bn_mat_identity, &rt_uniresource);
2616  if (BU_STR_EQUAL(intern->idb_meth->ft_name, "ID_COMBINATION")) {
2617  ret = brep_conversion_comb(intern, tmpname, suffix, wdbp, local2mm);
2618  if (ret) {
2619  bu_free(tmpname, "char");
2620  rt_db_free_internal(intern);
2621  break;
2622  }
2623  bu_strlcpy(newtree->tr_l.tl_name, tmpname, strlen(tmpname)+1);
2624  bu_free(tmpname, "char");
2625  break;
2626  }
2627  // It's a primitive. If it's a b-rep object, just duplicate it. Otherwise call the
2628  // function to convert it to b-rep.
2629  ON_Brep** brep;
2630 
2631  BU_ALLOC(brep, ON_Brep*);
2632 
2633  if (BU_STR_EQUAL(intern->idb_meth->ft_name, "ID_BREP")) {
2634  *brep = ((struct rt_brep_internal *)intern->idb_ptr)->brep->Duplicate();
2635  } else {
2636  ret = single_conversion(intern, brep, dbip);
2637  if (ret == -1) {
2638  bu_log("The brep conversion of %s is unsuccessful.\n", oldname);
2639  newtree = NULL;
2640  bu_free(tmpname, "char");
2641  bu_free(brep, "ON_Brep*");
2642  break;
2643  } else if (ret == -2) {
2644  ret = wdb_export(wdbp, tmpname, intern->idb_ptr, intern->idb_type, local2mm);
2645  if (ret) {
2646  bu_log("ERROR: failure writing [%s] to disk\n", tmpname);
2647  } else {
2648  bu_log("The conversion of [%s] (type: %s) is skipped. Implicit form remains as %s.\n",
2649  oldname, intern->idb_meth->ft_label, tmpname);
2650  bu_strlcpy(newtree->tr_l.tl_name, tmpname, strlen(tmpname)+1);
2651  }
2652  bu_free(tmpname, "char");
2653  bu_free(brep, "ON_Brep*");
2654  break;
2655  }
2656  }
2657  if (brep != NULL) {
2658  rt_brep_internal *bi;
2659  BU_ALLOC(bi, struct rt_brep_internal);
2660  bi->magic = RT_BREP_INTERNAL_MAGIC;
2661  bi->brep = *brep;
2662  ret = wdb_export(wdbp, tmpname, (void *)bi, ID_BREP, local2mm);
2663  if (ret) {
2664  bu_log("ERROR: failure writing [%s] to disk\n", tmpname);
2665  } else {
2666  bu_log("%s is made.\n", tmpname);
2667  bu_strlcpy(newtree->tr_l.tl_name, tmpname, strlen(tmpname)+1);
2668  }
2669  } else {
2670  bu_log("The brep conversion of %s is unsuccessful.\n", oldname);
2671  newtree = NULL;
2672  ret = -1;
2673  }
2674  bu_free(brep, "ON_Brep*");
2675  } else {
2676  bu_log("Cannot find %s.\n", oldname);
2677  newtree = NULL;
2678  ret = -1;
2679  }
2680  } else {
2681  bu_log("%s already exists.\n", tmpname);
2682  bu_strlcpy(newtree->tr_l.tl_name, tmpname, strlen(tmpname)+1);
2683  }
2684  bu_free(tmpname, "char");
2685  break;
2686  default:
2687  bu_log("OPCODE NOT IMPLEMENTED: %d\n", oldtree->tr_op);
2688  ret = -1;
2689  }
2690  if (comb)
2691  delete comb;
2692  return ret;
2693 }
2694 
2695 
2696 int
2697 brep_conversion_comb(struct rt_db_internal *old_internal, const char *name, const char *suffix, struct rt_wdb *wdbp, fastf_t local2mm)
2698 {
2699  RT_CK_COMB(old_internal->idb_ptr);
2700  rt_comb_internal *comb_internal;
2701  comb_internal = (rt_comb_internal *)old_internal->idb_ptr;
2702  int ret;
2703  if (comb_internal->tree == NULL) {
2704  // Empty tree. Also output an empty comb.
2705  ret = wdb_export(wdbp, name, comb_internal, ID_COMBINATION, local2mm);
2706  if (ret)
2707  return ret;
2708  bu_log("%s is made.\n", name);
2709  return 0;
2710  }
2711  RT_CK_TREE(comb_internal->tree);
2712  union tree *oldtree = comb_internal->tree;
2713  rt_comb_internal *new_internal;
2714 
2715  BU_ALLOC(new_internal, struct rt_comb_internal);
2716  *new_internal = *comb_internal;
2717  BU_ALLOC(new_internal->tree, union tree);
2718  RT_TREE_INIT(new_internal->tree);
2719 
2720  union tree *newtree = new_internal->tree;
2721 
2722  ret = brep_conversion_tree(wdbp->dbip, oldtree, newtree, suffix, wdbp, local2mm);
2723  if (!ret) {
2724  ret = wdb_export(wdbp, name, (void *)new_internal, ID_COMBINATION, local2mm);
2725  } else {
2726  bu_free(new_internal->tree, "tree");
2727  bu_free(new_internal, "rt_comb_internal");
2728  }
2729  if (!ret)
2730  bu_log("%s is made.\n", name);
2731 
2732  return ret;
2733 }
2734 
2735 int
2737  ON_Brep *brep,
2738  int surface_index,
2739  int i,
2740  int j,
2741  fastf_t dx,
2742  fastf_t dy,
2743  fastf_t dz)
2744 {
2745  ON_NurbsSurface *nurbsSurface = NULL;
2746  if (surface_index < 0 || surface_index >= brep->m_S.Count()) {
2747  bu_log("brep_translate_scv: invalid surface index %d\n", surface_index);
2748  return -1;
2749  }
2750 
2751  ON_Surface *surface = brep->m_S[surface_index];
2752  if (surface) {
2753  nurbsSurface = dynamic_cast<ON_NurbsSurface *>(surface);
2754  } else {
2755  return -1;
2756  }
2757 
2758  double *cv = NULL;
2759  if (nurbsSurface) {
2760  cv = nurbsSurface->CV(i, j);
2761  } else {
2762  return -2;
2763  }
2764 
2765  if (cv) {
2766  ON_3dPoint newPt;
2767  newPt.x = cv[X] + dx;
2768  newPt.y = cv[Y] + dy;
2769  newPt.z = cv[Z] + dz;
2770  nurbsSurface->SetCV(i, j, newPt);
2771  } else {
2772  return -3;
2773  }
2774 
2775  return 0;
2776 }
2777 
2778 int
2780  struct bu_vls *result,
2781  struct brep_specific *bs,
2782  int argc,
2783  const char *argv[])
2784 {
2785  // 0 1 2 3 4 5 6 7 8 9
2786  // brep <solid_name> translate SCV index i j dx dy dz
2787  if (argc != 10) {
2788  return -1;
2789  }
2790  ON_Brep *brep = bs->brep;
2791 
2792  if (BU_STR_EQUAL(argv[3], "SCV")) {
2793  int surface_index = atoi(argv[4]);
2794  int i = atoi(argv[5]);
2795  int j = atoi(argv[6]);
2796  fastf_t dx = atof(argv[7]);
2797  fastf_t dy = atof(argv[8]);
2798  fastf_t dz = atof(argv[9]);
2799 
2800  int ret = brep_translate_scv(brep, surface_index, i, j, dx, dy, dz);
2801  switch (ret) {
2802  case -1:
2803  bu_vls_printf(result, "No surface %d.\n", surface_index);
2804  break;
2805  case -2:
2806  bu_vls_printf(result, "Surface %d is not a NURBS surface.\n", surface_index);
2807  break;
2808  case -3:
2809  bu_vls_printf(result, "No control vertex (%d, %d).\n", i, j);
2810  }
2811  return ret;
2812  } else {
2813  return -1;
2814  }
2815 
2816  return 0;
2817 }
2818 
2819 
2820 int
2821 brep_command(struct bu_vls *vls, const char *solid_name, const struct rt_tess_tol *ttol, const struct bn_tol *tol, struct brep_specific* bs, struct rt_brep_internal* bi, struct bn_vlblock *vbp, int argc, const char *argv[], char *commtag)
2822 {
2823  const char *command;
2824  int ret = 0;
2825 
2826  if (argc == 2)
2827  command = "info";
2828  else
2829  command = (const char *) argv[2];
2830 
2831  snprintf(commtag, 64, "_BC_"); //default name pre/postfix tag for fake bn_vlblock solid
2832 
2833  if (BU_STR_EQUAL(command, "info")) {
2834  if (argc == 3) {
2835  ret = brep_info(bs, vls);
2836  info_usage(vls);
2837  } else if (argc == 4) {
2838  const char *part = argv[3];
2839  ON_Brep *brep = bs->brep;
2840  if (BU_STR_EQUAL(part, "S")) {
2841  for (int i = 0; i < brep->m_S.Count(); ++i) {
2842  ret = brep_surface_info(bs, vls, i);
2843  }
2844  } else if (BU_STR_EQUAL(part, "F")) {
2845  for (int i = 0; i < brep->m_F.Count(); ++i) {
2846  ret = brep_face_info(bs, vls, i);
2847  }
2848  } else if (BU_STR_EQUAL(part, "T")) {
2849  for (int i = 0; i < brep->m_T.Count(); ++i) {
2850  ret = brep_trim_info(bs, vls, i);
2851  }
2852  } else if (BU_STR_EQUAL(part, "E")) {
2853  for (int i = 0; i < brep->m_E.Count(); ++i) {
2854  ret = brep_edge_info(bs, vls, i);
2855  }
2856  } else if (BU_STR_EQUAL(part, "SB")) {
2857  for (int i = 0; i < brep->m_S.Count(); ++i) {
2858  ret = brep_surface_bezier_info(bs, vls, i);
2859  }
2860  } else if (BU_STR_EQUAL(part, "TB")) {
2861  for (int i = 0; i < brep->m_T.Count(); ++i) {
2862  ret = brep_trim_bezier_info(bs, vls, i);
2863  }
2864  } else if (BU_STR_EQUAL(part, "C")) {
2865  for (int i = 0; i < brep->m_C3.Count(); ++i) {
2866  ret = brep_curve_info(bs, vls, i);
2867  }
2868  }
2869  } else if (argc == 5) {
2870  const char *part = argv[3];
2871  const char *strindex = argv[4];
2872  std::set<int> elements;
2873  std::set<int>::iterator e_it;
2874  if (BU_STR_EQUAL(strindex, "all")) {
2875  ON_Brep *brep = bs->brep;
2876  if (BU_STR_EQUAL(part, "S")) {
2877  for (int i = 0; i < brep->m_S.Count(); ++i) {
2878  ret = brep_surface_info(bs, vls, i);
2879  }
2880  } else if (BU_STR_EQUAL(part, "F")) {
2881  for (int i = 0; i < brep->m_F.Count(); ++i) {
2882  ret = brep_face_info(bs, vls, i);
2883  }
2884  } else if (BU_STR_EQUAL(part, "T")) {
2885  for (int i = 0; i < brep->m_T.Count(); ++i) {
2886  ret = brep_trim_info(bs, vls, i);
2887  }
2888  } else if (BU_STR_EQUAL(part, "E")) {
2889  for (int i = 0; i < brep->m_E.Count(); ++i) {
2890  ret = brep_edge_info(bs, vls, i);
2891  }
2892  } else if (BU_STR_EQUAL(part, "L")) {
2893  for (int i = 0; i < brep->m_L.Count(); ++i) {
2894  ret = brep_loop_info(bs, vls, i);
2895  }
2896  } else if (BU_STR_EQUAL(part, "SB")) {
2897  for (int i = 0; i < brep->m_S.Count(); ++i) {
2898  ret = brep_surface_bezier_info(bs, vls, i);
2899  }
2900  } else if (BU_STR_EQUAL(part, "TB")) {
2901  for (int i = 0; i < brep->m_T.Count(); ++i) {
2902  ret = brep_trim_bezier_info(bs, vls, i);
2903  }
2904  } else if (BU_STR_EQUAL(part, "C")) {
2905  for (int i = 0; i < brep->m_C3.Count(); ++i) {
2906  ret = brep_curve_info(bs, vls, i);
2907  }
2908  }
2909  } else if (BU_STR_EQUAL(strindex, "?")) {
2910  info_usage(vls);
2911  } else {
2912  ON_Brep *brep = bs->brep;
2913  const char *dash = strchr(strindex, '-');
2914  const char *comma = strchr(strindex, ',');
2915  if (dash) {
2916  int startindex = -1;
2917  int endindex = -1;
2918  struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
2919  bu_vls_strcpy(&tmpstr, strindex);
2920  bu_vls_trunc(&tmpstr, dash - strindex);
2921  startindex = atoi(bu_vls_addr(&tmpstr));
2922  bu_vls_strcpy(&tmpstr, ++dash);
2923  endindex = atoi(bu_vls_addr(&tmpstr));
2924  bu_vls_free(&tmpstr);
2925  for (int elem = startindex; elem <= endindex; elem++) {
2926  elements.insert(elem);
2927  }
2928  } else if (comma) {
2929  struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
2930  bu_vls_strcpy(&tmpstr, strindex);
2931  while (strlen(bu_vls_addr(&tmpstr)) > 0) {
2932  struct bu_vls tmpstr2 = BU_VLS_INIT_ZERO;
2933  int idx = 0;
2934  bu_vls_strcpy(&tmpstr2, bu_vls_addr(&tmpstr));
2935  bu_vls_trunc(&tmpstr2, comma - bu_vls_addr(&tmpstr));
2936  idx = atoi(bu_vls_addr(&tmpstr2));
2937  bu_vls_free(&tmpstr2);
2938  elements.insert(idx);
2939  int stp = 0;
2940  while (idx >= 10) {
2941  int idx2 = idx / 10;
2942  idx = idx2;
2943  stp++;
2944  }
2945  bu_vls_nibble(&tmpstr, stp+2);
2946  comma = strchr(bu_vls_addr(&tmpstr), ',');
2947  }
2948  bu_vls_free(&tmpstr);
2949  } else {
2950  int idx = atoi(strindex);
2951  elements.insert(idx);
2952  }
2953  if (BU_STR_EQUAL(part, "S")) {
2954  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
2955  if (*e_it < brep->m_S.Count()) ret = brep_surface_info(bs, vls, (*e_it));
2956  }
2957  } else if (BU_STR_EQUAL(part, "F")) {
2958  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
2959  if (*e_it < brep->m_F.Count()) ret = brep_face_info(bs, vls, (*e_it));
2960  }
2961  } else if (BU_STR_EQUAL(part, "T")) {
2962  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
2963  if (*e_it < brep->m_T.Count()) ret = brep_trim_info(bs, vls, (*e_it));
2964  }
2965  } else if (BU_STR_EQUAL(part, "E")) {
2966  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
2967  if (*e_it < brep->m_E.Count()) ret = brep_edge_info(bs, vls, (*e_it));
2968  }
2969  } else if (BU_STR_EQUAL(part, "L")) {
2970  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
2971  if (*e_it < brep->m_L.Count()) ret = brep_loop_info(bs, vls, (*e_it));
2972  }
2973  } else if (BU_STR_EQUAL(part, "SB")) {
2974  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
2975  if (*e_it < brep->m_S.Count()) ret = brep_surface_bezier_info(bs, vls, (*e_it));
2976  }
2977  } else if (BU_STR_EQUAL(part, "TB")) {
2978  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
2979  if (*e_it < brep->m_T.Count()) ret = brep_trim_bezier_info(bs, vls, (*e_it));
2980  }
2981  } else if (BU_STR_EQUAL(part, "C")) {
2982  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
2983  if (*e_it < brep->m_C3.Count()) ret = brep_curve_info(bs, vls, (*e_it));
2984  }
2985  }
2986  }
2987  }
2988  } else if (BU_STR_EQUAL(command, "plot")) {
2989  if (argc == 3) {
2990  plot_usage(vls);
2991  } else if (argc >= 4) {
2992  const char *part = argv[3];
2993  int numpoints = -1;
2994  int plotres = 100;
2995  std::set<int> elements;
2996  std::set<int>::iterator e_it;
2997  if (argc == 6) {
2998  const char *strres = argv[5];
2999  plotres = numpoints = atoi(strres);
3000  }
3001  if (argc >= 5) {
3002  const char *str = argv[4];
3003  if (BU_STR_EQUAL(str, "all")) {
3004  ON_Brep *brep = bs->brep;
3005  if (BU_STR_EQUAL(part, "S")) {
3006  for (int i = 0; i < brep->m_S.Count(); ++i) {
3007  elements.insert(i);
3008  }
3009  } else if (BU_STR_EQUAL(part, "F")) {
3010  for (int i = 0; i < brep->m_F.Count(); ++i) {
3011  elements.insert(i);
3012  }
3013  } else if (BU_STR_EQUAL(part, "T")) {
3014  for (int i = 0; i < brep->m_T.Count(); ++i) {
3015  elements.insert(i);
3016  }
3017  } else if (BU_STR_EQUAL(part, "E")) {
3018  for (int i = 0; i < brep->m_E.Count(); ++i) {
3019  elements.insert(i);
3020  }
3021  } else if (BU_STR_EQUAL(part, "L")) {
3022  for (int i = 0; i < brep->m_L.Count(); ++i) {
3023  elements.insert(i);
3024  }
3025  } else if (BU_STR_EQUAL(part, "SB")) {
3026  for (int i = 0; i < brep->m_S.Count(); ++i) {
3027  elements.insert(i);
3028  }
3029  } else if (BU_STR_EQUAL(part, "TB")) {
3030  for (int i = 0; i < brep->m_T.Count(); ++i) {
3031  elements.insert(i);
3032  }
3033  } else if (BU_STR_EQUAL(part, "C")) {
3034  for (int i = 0; i < brep->m_C3.Count(); ++i) {
3035  elements.insert(i);
3036  }
3037  }
3038  } else if (BU_STR_EQUAL(str, "?")) {
3039  plot_usage(vls);
3040  } else {
3041  const char *dash = strchr(str, '-');
3042  const char *comma = strchr(str, ',');
3043  if (dash) {
3044  int startindex = -1;
3045  int endindex = -1;
3046  struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
3047  bu_vls_strcpy(&tmpstr, str);
3048  bu_vls_trunc(&tmpstr, dash - str);
3049  startindex = atoi(bu_vls_addr(&tmpstr));
3050  bu_vls_strcpy(&tmpstr, ++dash);
3051  endindex = atoi(bu_vls_addr(&tmpstr));
3052  bu_vls_free(&tmpstr);
3053  for (int elem = startindex; elem <= endindex; elem++) {
3054  elements.insert(elem);
3055  }
3056  } else if (comma) {
3057  struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
3058  bu_vls_strcpy(&tmpstr, str);
3059  while (strlen(bu_vls_addr(&tmpstr)) > 0) {
3060  struct bu_vls tmpstr2 = BU_VLS_INIT_ZERO;
3061  int idx = 0;
3062  bu_vls_strcpy(&tmpstr2, bu_vls_addr(&tmpstr));
3063  bu_vls_trunc(&tmpstr2, comma - bu_vls_addr(&tmpstr));
3064  idx = atoi(bu_vls_addr(&tmpstr2));
3065  bu_vls_free(&tmpstr2);
3066  elements.insert(idx);
3067  int stp = 0;
3068  while (idx >= 10) {
3069  int idx2 = idx / 10;
3070  idx = idx2;
3071  stp++;
3072  }
3073  bu_vls_nibble(&tmpstr, stp+2);
3074  comma = strchr(bu_vls_addr(&tmpstr), ',');
3075  }
3076  bu_vls_free(&tmpstr);
3077  } else {
3078  int idx = atoi(str);
3079  elements.insert(idx);
3080  }
3081  }
3082  }
3083  if (BU_STR_EQUAL(part, "S")) {
3084  snprintf(commtag, 64, "_BC_S_");
3085  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3086  ret = brep_surface_plot(vls, bs, bi, vbp, (*e_it), plotres);
3087  }
3088  } else if (BU_STR_EQUAL(part, "Suv")) {
3089  double u = 0.0;
3090  double v = 0.0;
3091  if (argc == 7) {
3092  const char *ustr = argv[5];
3093  const char *vstr = argv[6];
3094 
3095  u = atof(ustr);
3096  v = atof(vstr);
3097  }
3098  snprintf(commtag, 64, "_BC_Suv_");
3099  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3100  ret = brep_surface_uv_plot(vls, bs, bi, vbp, (*e_it), u, v);
3101  }
3102  } else if (BU_STR_EQUAL(part, "UV")) {
3103  ON_Interval u;
3104  ON_Interval v;
3105  if (argc == 9) {
3106  const char *u1str = argv[5];
3107  const char *u2str = argv[6];
3108  const char *v1str = argv[7];
3109  const char *v2str = argv[8];
3110 
3111  u.m_t[0] = atof(u1str);
3112  u.m_t[1] = atof(u2str);
3113  v.m_t[0] = atof(v1str);
3114  v.m_t[1] = atof(v2str);
3115  }
3116  snprintf(commtag, 64, "_BC_UV_");
3117  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3118  ret = brep_surface_uv_plot(vls, bs, bi, vbp, (*e_it), u, v);
3119  }
3120  } else if (BU_STR_EQUAL(part, "I")) {
3121  snprintf(commtag, 64, "_BC_I_");
3122  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3123  ret = brep_isosurface_plot(vls, bs, bi, vbp, (*e_it), plotres);
3124  }
3125  } else if (BU_STR_EQUAL(part, "SN")) {
3126  snprintf(commtag, 64, "_BC_SN_");
3127  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3128  ret = brep_surface_normal_plot(vls, bs, bi, vbp, (*e_it),
3129  plotres);
3130  }
3131  } else if (BU_STR_EQUAL(part, "KN2d")) {
3132  snprintf(commtag, 64, "_BC_KN2d_");
3133  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3134  ret = brep_surface_knot_plot(vls, bs, bi, vbp, (*e_it), false);
3135  }
3136  } else if (BU_STR_EQUAL(part, "KN")) {
3137  snprintf(commtag, 64, "_BC_KN_");
3138  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3139  ret = brep_surface_knot_plot(vls, bs, bi, vbp, (*e_it), true);
3140  }
3141  } else if (BU_STR_EQUAL(part, "F")) {
3142  snprintf(commtag, 64, "_BC_F_");
3143  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3144  ret = brep_facetrim_plot(vls, bs, bi, vbp, (*e_it), plotres,
3145  true);
3146  }
3147  } else if (BU_STR_EQUAL(part, "F2d")) {
3148  snprintf(commtag, 64, "_BC_F2d_");
3149  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3150  ret = brep_facetrim_plot(vls, bs, bi, vbp, (*e_it), plotres,
3151  false);
3152  }
3153  } else if (BU_STR_EQUAL(part, "FCDT")) {
3154  snprintf(commtag, 64, "_BC_FCDT_");
3155  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3156  ret = brep_facecdt_plot(vls, solid_name, ttol, tol, bs, bi, vbp, (*e_it), 0);
3157  }
3158  } else if (BU_STR_EQUAL(part, "FCDTw")) {
3159  snprintf(commtag, 64, "_BC_FCDT_");
3160  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3161  ret = brep_facecdt_plot(vls, solid_name, ttol, tol, bs, bi, vbp, (*e_it), 1, numpoints);
3162  }
3163  } else if (BU_STR_EQUAL(part, "FCDT2d")) {
3164  snprintf(commtag, 64, "_BC_FCDT2d_");
3165  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3166  ret = brep_facecdt_plot(vls, solid_name, ttol, tol, bs, bi, vbp, (*e_it), 2);
3167  }
3168  } else if (BU_STR_EQUAL(part, "FCDTm2d")) {
3169  snprintf(commtag, 64, "_BC_FCDTm2d_");
3170  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3171  ret = brep_facecdt_plot(vls, solid_name, ttol, tol, bs, bi, vbp, (*e_it), 3, numpoints);
3172  }
3173  } else if (BU_STR_EQUAL(part, "FCDTp2d")) {
3174  snprintf(commtag, 64, "_BC_FCDTp2d_");
3175  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3176  ret = brep_facecdt_plot(vls, solid_name, ttol, tol, bs, bi, vbp, (*e_it), 4, numpoints);
3177  }
3178  } else if (BU_STR_EQUAL(part, "SBB")) {
3179  snprintf(commtag, 64, "_BC_SBB_");
3180  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3181  ret = brep_surfaceleafs_plot(vls, bs, bi, vbp, true, (*e_it),
3182  plotres);
3183  }
3184  } else if (BU_STR_EQUAL(part, "SBB2d")) {
3185  snprintf(commtag, 64, "_BC_SBB2d_");
3186  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3187  ret = brep_surfaceleafs_plot(vls, bs, bi, vbp, false, (*e_it),
3188  plotres);
3189  }
3190  } else if (BU_STR_EQUAL(part, "TD")) {
3191  snprintf(commtag, 64, "_BC_TD_");
3192  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3193  ret = brep_trim_direction_plot(vls, bs, bi, vbp, (*e_it),
3194  plotres);
3195  }
3196  } else if (BU_STR_EQUAL(part, "T")) {
3197  snprintf(commtag, 64, "_BC_T_");
3198  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3199  ret = brep_trim_plot(vls, bs, bi, vbp, (*e_it), plotres, true);
3200  }
3201  } else if (BU_STR_EQUAL(part, "T2d")) {
3202  snprintf(commtag, 64, "_BC_T2d_");
3203  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3204  ret = brep_trim_plot(vls, bs, bi, vbp, (*e_it), plotres, false);
3205  }
3206  } else if (BU_STR_EQUAL(part, "L")) {
3207  snprintf(commtag, 64, "_BC_L_");
3208  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3209  ret = brep_loop_plot(vls, bs, bi, vbp, (*e_it), plotres, true);
3210  }
3211  } else if (BU_STR_EQUAL(part, "L2d")) {
3212  snprintf(commtag, 64, "_BC_L2d_");
3213  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3214  ret = brep_loop_plot(vls, bs, bi, vbp, (*e_it), plotres, false);
3215  }
3216  } else if (BU_STR_EQUAL(part, "TBB")) {
3217  snprintf(commtag, 64, "_BC_TBB_");
3218  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3219  ret = brep_trimleafs_plot(vls, bs, bi, vbp, true, (*e_it),
3220  plotres);
3221  }
3222  } else if (BU_STR_EQUAL(part, "TBB2d")) {
3223  snprintf(commtag, 64, "_BC_TBB2d_");
3224  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3225  ret = brep_trimleafs_plot(vls, bs, bi, vbp, false, (*e_it),
3226  plotres);
3227  }
3228  } else if (BU_STR_EQUAL(part, "E")) {
3229  snprintf(commtag, 64, "_BC_E_");
3230  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3231  ret = brep_edge3d_plot(vls, bs, bi, vbp, (*e_it), plotres);
3232  }
3233  } else if (BU_STR_EQUAL(part, "SCV")) {
3234  snprintf(commtag, 64, "_BC_SCV_");
3235  for (e_it = elements.begin(); e_it != elements.end(); e_it++) {
3236  ret = brep_surface_cv_plot(vls, bs, bi, vbp, (*e_it));
3237  }
3238  }
3239  }
3240  } else if (BU_STR_EQUAL(command, "translate")) {
3241  ret = translate_command(vls, bs, argc, argv);
3242  }
3243  return ret;
3244 }
3245 
3246 
3247 int
3248 brep_intersect_point_point(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
3249 {
3250  RT_CK_DB_INTERNAL(intern1);
3251  RT_CK_DB_INTERNAL(intern2);
3252  struct rt_brep_internal *bi1, *bi2;
3253  bi1 = (struct rt_brep_internal *)intern1->idb_ptr;
3254  bi2 = (struct rt_brep_internal *)intern2->idb_ptr;
3255  RT_BREP_CK_MAGIC(bi1);
3256  RT_BREP_CK_MAGIC(bi2);
3257 
3258  ON_Brep *brep1 = bi1->brep;
3259  ON_Brep *brep2 = bi2->brep;
3260 
3261  if (i < 0 || i >= brep1->m_V.Count() || j < 0 || j >= brep2->m_V.Count()) {
3262  bu_log("Out of range: \n");
3263  bu_log("\t0 <= i <= %d\n", brep1->m_V.Count() - 1);
3264  bu_log("\t0 <= j <= %d\n", brep2->m_V.Count() - 1);
3265  return -1;
3266  }
3267 
3268  ON_ClassArray<ON_PX_EVENT> events;
3269  if (ON_Intersect(brep1->m_V[i].Point(), brep2->m_V[j].Point(), events)) {
3270  for (int k = 0; k < events.Count(); k++) {
3271  ON_wString wstr;
3272  ON_TextLog textlog(wstr);
3273  events[k].Dump(textlog);
3274  ON_String str = ON_String(wstr);
3275  bu_log("Intersection event %d:\n %s", k + 1, str.Array());
3276  }
3277  } else {
3278  bu_log("No intersection.\n");
3279  }
3280 
3281  return 0;
3282 }
3283 
3284 
3285 int
3286 brep_intersect_point_curve(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
3287 {
3288  RT_CK_DB_INTERNAL(intern1);
3289  RT_CK_DB_INTERNAL(intern2);
3290  struct rt_brep_internal *bi1, *bi2;
3291  bi1 = (struct rt_brep_internal *)intern1->idb_ptr;
3292  bi2 = (struct rt_brep_internal *)intern2->idb_ptr;
3293  RT_BREP_CK_MAGIC(bi1);
3294  RT_BREP_CK_MAGIC(bi2);
3295 
3296  ON_Brep *brep1 = bi1->brep;
3297  ON_Brep *brep2 = bi2->brep;
3298 
3299  if (i < 0 || i >= brep1->m_V.Count() || j < 0 || j >= brep2->m_C3.Count()) {
3300  bu_log("Out of range: \n");
3301  bu_log("\t0 <= i <= %d\n", brep1->m_V.Count() - 1);
3302  bu_log("\t0 <= j <= %d\n", brep2->m_C3.Count() - 1);
3303  return -1;
3304  }
3305 
3306  ON_ClassArray<ON_PX_EVENT> events;
3307  if (ON_Intersect(brep1->m_V[i].Point(), *(brep2->m_C3[j]), events)) {
3308  for (int k = 0; k < events.Count(); k++) {
3309  ON_wString wstr;
3310  ON_TextLog textlog(wstr);
3311  events[k].Dump(textlog);
3312  ON_String str = ON_String(wstr);
3313  bu_log("Intersection event %d:\n %s", k + 1, str.Array());
3314  }
3315  } else {
3316  bu_log("No intersection.\n");
3317  }
3318 
3319  return 0;
3320 }
3321 
3322 
3323 int
3324 brep_intersect_point_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
3325 {
3326  RT_CK_DB_INTERNAL(intern1);
3327  RT_CK_DB_INTERNAL(intern2);
3328  struct rt_brep_internal *bi1, *bi2;
3329  bi1 = (struct rt_brep_internal *)intern1->idb_ptr;
3330  bi2 = (struct rt_brep_internal *)intern2->idb_ptr;
3331  RT_BREP_CK_MAGIC(bi1);
3332  RT_BREP_CK_MAGIC(bi2);
3333 
3334  ON_Brep *brep1 = bi1->brep;
3335  ON_Brep *brep2 = bi2->brep;
3336 
3337  if (i < 0 || i >= brep1->m_V.Count() || j < 0 || j >= brep2->m_S.Count()) {
3338  bu_log("Out of range: \n");
3339  bu_log("\t0 <= i <= %d\n", brep1->m_V.Count() - 1);
3340  bu_log("\t0 <= j <= %d\n", brep2->m_S.Count() - 1);
3341  return -1;
3342  }
3343 
3344  ON_ClassArray<ON_PX_EVENT> events;
3345  if (ON_Intersect(brep1->m_V[i].Point(), *(brep2->m_S[j]), events)) {
3346  for (int k = 0; k < events.Count(); k++) {
3347  ON_wString wstr;
3348  ON_TextLog textlog(wstr);
3349  events[k].Dump(textlog);
3350  ON_String str = ON_String(wstr);
3351  bu_log("Intersection event %d:\n %s", k + 1, str.Array());
3352  }
3353  } else {
3354  bu_log("No intersection.\n");
3355  }
3356 
3357  return 0;
3358 }
3359 
3360 
3361 int
3362 brep_intersect_curve_curve(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
3363 {
3364  RT_CK_DB_INTERNAL(intern1);
3365  RT_CK_DB_INTERNAL(intern2);
3366  struct rt_brep_internal *bi1, *bi2;
3367  bi1 = (struct rt_brep_internal *)intern1->idb_ptr;
3368  bi2 = (struct rt_brep_internal *)intern2->idb_ptr;
3369  RT_BREP_CK_MAGIC(bi1);
3370  RT_BREP_CK_MAGIC(bi2);
3371 
3372  ON_Brep *brep1 = bi1->brep;
3373  ON_Brep *brep2 = bi2->brep;
3374 
3375  if (i < 0 || i >= brep1->m_C3.Count() || j < 0 || j >= brep2->m_C3.Count()) {
3376  bu_log("Out of range: \n");
3377  bu_log("\t0 <= i <= %d\n", brep1->m_C3.Count() - 1);
3378  bu_log("\t0 <= j <= %d\n", brep2->m_C3.Count() - 1);
3379  return -1;
3380  }
3381 
3382  ON_SimpleArray<ON_X_EVENT> events;
3383  if (ON_Intersect(brep1->m_C3[i], brep2->m_C3[j], events)) {
3384  for (int k = 0; k < events.Count(); k++) {
3385  ON_wString wstr;
3386  ON_TextLog textlog(wstr);
3387  events[k].Dump(textlog);
3388  ON_String str = ON_String(wstr);
3389  bu_log("Intersection event %d:\n %s", k + 1, str.Array());
3390  }
3391  } else {
3392  bu_log("No intersection.\n");
3393  }
3394 
3395  return 0;
3396 }
3397 
3398 
3399 int
3400 brep_intersect_curve_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
3401 {
3402  RT_CK_DB_INTERNAL(intern1);
3403  RT_CK_DB_INTERNAL(intern2);
3404  struct rt_brep_internal *bi1, *bi2;
3405  bi1 = (struct rt_brep_internal *)intern1->idb_ptr;
3406  bi2 = (struct rt_brep_internal *)intern2->idb_ptr;
3407  RT_BREP_CK_MAGIC(bi1);
3408  RT_BREP_CK_MAGIC(bi2);
3409 
3410  ON_Brep *brep1 = bi1->brep;
3411  ON_Brep *brep2 = bi2->brep;
3412 
3413  if (i < 0 || i >= brep1->m_C3.Count() || j < 0 || j >= brep2->m_S.Count()) {
3414  bu_log("Out of range: \n");
3415  bu_log("\t0 <= i <= %d\n", brep1->m_C3.Count() - 1);
3416  bu_log("\t0 <= j <= %d\n", brep2->m_S.Count() - 1);
3417  return -1;
3418  }
3419 
3420  ON_SimpleArray<ON_X_EVENT> events;
3421  if (ON_Intersect(brep1->m_C3[i], brep2->m_S[j], events)) {
3422  for (int k = 0; k < events.Count(); k++) {
3423  ON_wString wstr;
3424  ON_TextLog textlog(wstr);
3425  events[k].Dump(textlog);
3426  ON_String str = ON_String(wstr);
3427  bu_log("Intersection event %d:\n %s", k + 1, str.Array());
3428  }
3429  } else {
3430  bu_log("No intersection.\n");
3431  }
3432 
3433  return 0;
3434 }
3435 
3436 
3437 int
3438 brep_intersect_surface_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j, struct bn_vlblock *vbp)
3439 {
3440  RT_CK_DB_INTERNAL(intern1);
3441  RT_CK_DB_INTERNAL(intern2);
3442  struct rt_brep_internal *bi1, *bi2;
3443  bi1 = (struct rt_brep_internal *)intern1->idb_ptr;
3444  bi2 = (struct rt_brep_internal *)intern2->idb_ptr;
3445  RT_BREP_CK_MAGIC(bi1);
3446  RT_BREP_CK_MAGIC(bi2);
3447 
3448  ON_Brep *brep1 = bi1->brep;
3449  ON_Brep *brep2 = bi2->brep;
3450 
3451  ON_NurbsSurface surf1;
3452  ON_NurbsSurface surf2;
3453 
3454  if (i < 0 || i >= brep1->m_S.Count() || j < 0 || j >= brep2->m_S.Count()) {
3455  bu_log("Out of range: \n");
3456  bu_log("\t0 <= i <= %d\n", brep1->m_S.Count() - 1);
3457  bu_log("\t0 <= j <= %d\n", brep2->m_S.Count() - 1);
3458  return -1;
3459  }
3460 
3461  brep1->m_S[i]->GetNurbForm(surf1);
3462  brep2->m_S[j]->GetNurbForm(surf2);
3463 
3464  ON_ClassArray<ON_SSX_EVENT> events;
3465  if (ON_Intersect(&surf1, &surf2, events) < 0) {
3466  bu_log("Intersection failed\n");
3467  return -1;
3468  }
3469 
3470  plotsurface(surf1, vbp, 100, 10, PURERED);
3471  plotsurface(surf2, vbp, 100, 10, BLUE);
3472 
3473  // Plot the intersection curves (or points) (3D and 2D)
3474  for (int k = 0; k < events.Count(); k++) {
3475  switch (events[k].m_type) {
3476  case ON_SSX_EVENT::ssx_overlap:
3477  case ON_SSX_EVENT::ssx_tangent:
3478  case ON_SSX_EVENT::ssx_transverse:
3479  plotcurveonsurface(events[k].m_curveA, &surf1, vbp, 1000, PEACH);
3480  plotcurveonsurface(events[k].m_curveB, &surf2, vbp, 1000, DARKVIOLET);
3481  plotcurve(*(events[k].m_curve3d), vbp, 1000, GREEN);
3482  break;
3483  case ON_SSX_EVENT::ssx_tangent_point:
3484  case ON_SSX_EVENT::ssx_transverse_point:
3485  plotpoint(surf1.PointAt(events[k].m_pointA.x, events[k].m_pointB.y), vbp, PEACH);
3486  plotpoint(surf2.PointAt(events[k].m_pointB.x, events[k].m_pointB.y), vbp, DARKVIOLET);
3487  plotpoint(events[k].m_point3d, vbp, GREEN);
3488  break;
3489  default:
3490  break;
3491  }
3492  }
3493 
3494  return 0;
3495 }
3496 
3497 
3498 /** @} */
3499 
3500 /*
3501  * Local Variables:
3502  * mode: C++
3503  * tab-width: 8
3504  * c-basic-offset: 4
3505  * indent-tabs-mode: t
3506  * c-file-style: "stroustrup"
3507  * End:
3508  * ex: shiftwidth=4 tabstop=8
3509  */
int brep_edge3d_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, int plotres)
Definition: raytrace.h:800
bool ON_Intersect(const ON_3dPoint &pointA, const ON_3dPoint &pointB, ON_ClassArray< ON_PX_EVENT > &x, double tol)
Definition: intersect.cpp:647
void plottrim2d(ON_BrepFace &face, struct bn_vlblock *vbp, int plotres)
Definition: brep_debug.cpp:384
void plotcurve(ON_Curve &curve, struct bn_vlblock *vbp, int plotres, const int red=255, const int green=255, const int blue=0)
Definition: brep_debug.cpp:717
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
int rt_db_get_internal(struct rt_db_internal *ip, const struct directory *dp, const struct db_i *dbip, const mat_t mat, struct resource *resp)
Definition: dir.c:76
int brep_surface_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, int plotres)
int brep_surface_knot_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, bool dim3d)
int bu_hsv_to_rgb(fastf_t *hsv, unsigned char *rgb)
Definition: color.c:121
Definition: list.h:118
int brep_trim_bezier_info(struct brep_specific *bs, struct bu_vls *vls, int ti)
void plotpoint(const ON_3dPoint &point, struct bn_vlblock *vbp, const int red=255, const int green=255, const int blue=0)
Definition: brep_debug.cpp:765
#define BB_PLOT_VLIST(min, max)
Definition: brep_debug.cpp:111
double dist
>= 0
Definition: tol.h:73
const mat_t bn_mat_identity
Matrix and vector functionality.
Definition: mat.c:46
int brep_isosurface_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, int plotres)
int brep_command(struct bu_vls *vls, const char *solid_name, const struct rt_tess_tol *ttol, const struct bn_tol *tol, struct brep_specific *bs, struct rt_brep_internal *bi, struct bn_vlblock *vbp, int argc, const char *argv[], char *commtag)
struct db_i * dbip
Definition: raytrace.h:1266
if lu s
Definition: nmg_mod.c:3860
Definition: clone.c:90
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
#define VSET(a, b, c, d)
Definition: color.c:53
#define VSETALL(a, s)
Definition: color.c:54
#define OP_XOR
Binary: L xor R, not both.
Definition: raytrace.h:1130
#define N
Definition: randmt.c:39
Definition: nmg_tri.c:75
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
void bu_vls_nibble(struct bu_vls *vp, off_t len)
Definition: vls.c:217
double dist_sq
dist * dist
Definition: tol.h:74
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
#define st
Definition: clone.c:114
int brep_surface_info(struct brep_specific *bs, struct bu_vls *vls, int si)
Definition: brep_debug.cpp:857
void plot_usage(struct bu_vls *vls)
int translate_command(struct bu_vls *result, struct brep_specific *bs, int argc, const char *argv[])
#define RT_CK_COMB(_p)
Definition: raytrace.h:955
#define BN_TOL_MAGIC
Definition: magic.h:74
#define SMALL_FASTF
Definition: defines.h:342
int brep_translate_scv(ON_Brep *brep, int surface_index, int i, int j, fastf_t dx, fastf_t dy, fastf_t dz)
#define LINE_PLOT(p1, p2)
Definition: brep_debug.h:111
int single_conversion(struct rt_db_internal *intern, ON_Brep **brep, const struct db_i *dbip)
Header file for the BRL-CAD common definitions.
#define OP_XNOP
Unary: L, mark region.
Definition: raytrace.h:1136
void plotFaceFromSurfaceTree(SurfaceTree *st, struct bn_vlblock *vbp, int isocurveres, int gridres)
void plotsurface(ON_Surface &surf, struct bn_vlblock *vbp, int isocurveres, int gridres, const int red=200, const int green=200, const int blue=200)
Definition: brep_debug.cpp:578
void drawisoUCheckForTrim(SurfaceTree *st, struct bn_vlblock *vbp, fastf_t from, fastf_t to, fastf_t v, int curveres)
#define YELLOW
Definition: brep_debug.h:88
#define ID_COMBINATION
Combination Record.
Definition: raytrace.h:499
ON_Brep * brep
Definition: brep_local.h:33
#define PURERED
Definition: brep_debug.h:85
char ft_label[9]
Definition: raytrace.h:2044
void plotFace(SurfaceTree *st, struct bn_vlblock *vbp, int isocurveres, int gridres)
ustring width
int brep_intersect_point_curve(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
#define RT_TREE_INIT(_p)
Definition: raytrace.h:1189
void bu_rgb_to_hsv(unsigned char *rgb, fastf_t *hsv)
Definition: color.c:60
union tree * tb_left
Definition: raytrace.h:1149
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
void drawisoV(SurfaceTree *st, struct bn_vlblock *vbp, fastf_t from, fastf_t to, fastf_t u, int curveres)
if(share_geom)
Definition: nmg_mod.c:3829
char * strchr(const char *sp, int c)
struct bu_list * rt_vlblock_find(struct bn_vlblock *vbp, int r, int g, int b)
Definition: vlist.c:98
int idb_major_type
Definition: raytrace.h:192
int brep_surface_normal_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, int plotres)
int brep_facetrim_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, int plotres, bool dim3d)
int brep_intersect_point_point(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int brep_conversion(struct rt_db_internal *in, struct rt_db_internal *out, const struct db_i *dbip)
#define OP_SUBTRACT
Binary: L subtract R.
Definition: raytrace.h:1129
#define RT_BREP_INTERNAL_MAGIC
Definition: magic.h:86
Definition: color.c:49
int wdb_export(struct rt_wdb *wdbp, const char *name, void *gp, int id, double local2mm)
Definition: wdb.c:265
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define OP_INTERSECT
Binary: L intersect R.
Definition: raytrace.h:1128
int brep_surfaceleafs_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, bool dim3d, int index, int)
#define RT_ADD_VLIST(hd, pnt, draw)
Definition: raytrace.h:1865
#define OP_DB_LEAF
Leaf of combination, db fmt.
Definition: raytrace.h:1139
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
void drawisoVCheckForTrim(SurfaceTree *st, struct bn_vlblock *vbp, fastf_t from, fastf_t to, fastf_t u, int curveres)
void plotcurveonsurface(ON_Curve *curve, ON_Surface *surface, struct bn_vlblock *vbp, int plotres, const int red=255, const int green=255, const int blue=0)
Definition: brep_debug.cpp:776
int brep_facecdt_plot(struct bu_vls *vls, const char *solid_name, const struct rt_tess_tol *ttol, const struct bn_tol *tol, struct brep_specific *bs, struct rt_brep_internal *bi, struct bn_vlblock *vbp, int index, int plottype, int num_points=-1)
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
void pdv_3space(register FILE *plotfp, const fastf_t *min, const fastf_t *max)
Definition: plot3.c:560
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define BN_VLIST_LINE_MOVE
Definition: vlist.h:82
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
#define bu_strlcpy(dst, src, size)
Definition: str.h:60
void plotleaf3d(BBNode *bb, double within_distance_tol)
Definition: brep_debug.cpp:255
int brep_trim_info(struct brep_specific *bs, struct bu_vls *vls, int ti)
int brep_loop_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, int plotres, bool dim3d)
#define BN_VLIST_LINE_DRAW
Definition: vlist.h:83
#define DARKVIOLET
Definition: brep_debug.h:78
int brep_surface_bezier_info(struct brep_specific *bs, struct bu_vls *vls, int si)
Definition: brep_debug.cpp:901
int brep_intersect_curve_curve(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
Coord * point
Definition: chull3d.cpp:52
void plottrim(ON_BrepFace &face, struct bn_vlblock *vbp, int plotres, bool dim3d)
Definition: brep_debug.cpp:341
#define BN_TOL_DIST
Definition: tol.h:109
char * tl_name
Name of this leaf (bu_strdup'ed)
Definition: raytrace.h:1174
void plotsurfaceknots(ON_Surface &surf, struct bn_vlblock *vbp, bool dim3d)
Definition: brep_debug.cpp:662
struct tree::tree_node tr_b
char ft_name[17]
Definition: raytrace.h:2043
#define UNUSED(parameter)
Definition: common.h:239
#define OP_GUARD
Unary: not L, or else!
Definition: raytrace.h:1135
FILE * brep_plot_file(const char *pname)
Definition: brep_debug.cpp:84
goto out
Definition: nmg_mod.c:3846
void info_usage(struct bu_vls *vls)
void drawisoU(SurfaceTree *st, struct bn_vlblock *vbp, fastf_t from, fastf_t to, fastf_t v, int curveres)
Support for uniform tolerances.
Definition: tol.h:71
void drawBBNode(SurfaceTree *st, struct bn_vlblock *vbp, BBNode *node)
int brep_trim_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, int plotres, bool dim3d)
int brep_face_info(struct brep_specific *bs, struct bu_vls *vls, int fi)
Definition: brep_debug.cpp:968
int brep_trimleafs_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, bool dim3d, int index, int)
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
void plotleafuv(BBNode *bb)
Definition: brep_debug.cpp:315
int brep_conversion_comb(struct rt_db_internal *old_internal, const char *name, const char *suffix, struct rt_wdb *wdbp, fastf_t local2mm)
#define COLOR_PLOT(r, g, b)
Definition: brep_debug.h:97
#define ID_BREP
B-rep object.
Definition: raytrace.h:509
int brep_edge_info(struct brep_specific *bs, struct bu_vls *vls, int ei)
#define GREEN
Definition: brep_debug.h:86
#define MAGENTA
Definition: brep_debug.h:89
#define BN_VLIST_POINT_SIZE
specify point pixel size
Definition: vlist.h:95
double perp
nearly 0
Definition: tol.h:75
int brep_info(struct brep_specific *bs, struct bu_vls *vls)
Definition: brep_debug.cpp:840
struct tree::tree_db_leaf tr_l
union tree * tb_right
Definition: raytrace.h:1150
void plotUVDomain2d(ON_BrepFace &face, struct bn_vlblock *vbp)
Definition: brep_debug.cpp:425
void * idb_ptr
Definition: raytrace.h:195
uint32_t magic
Definition: tol.h:72
const struct rt_functab OBJ[]
Definition: table.c:159
#define BLUE
Definition: brep_debug.h:87
union tree * tree
Leading to tree_db_leaf leaves.
Definition: raytrace.h:938
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
int brep_intersect_curve_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
void poly2tri_CDT(struct bu_list *vhead, ON_BrepFace &face, const struct rt_tess_tol *ttol, const struct bn_tol *tol, const struct rt_view_info *info, bool watertight=false, int plottype=0, int num_points=-1.0)
Definition: brep.cpp:3751
void bezier(point2d_t *V, int degree, double t, point2d_t *Left, point2d_t *Right, point2d_t eval_pt, point2d_t normal)
Definition: bezier.c:192
#define BB_PLOT(p1, p2)
Definition: brep_debug.h:112
void plottrimleafs(SurfaceTree *st, struct bn_vlblock *vbp, bool dim3d)
Definition: brep_debug.cpp:212
int idb_minor_type
ID_xxx.
Definition: raytrace.h:193
#define A
Definition: msr.c:51
Definition: color.c:51
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
int brep_surface_uv_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, double u, double v)
void(* ft_brep)(ON_Brep **, struct rt_db_internal *, const struct bn_tol *)
Definition: raytrace.h:2126
#define RT_CK_TREE(_p)
Definition: raytrace.h:1182
#define PEACH
Definition: brep_debug.h:74
void plotsurfacenormals(ON_Surface &surf, struct bn_vlblock *vbp, int gridres)
Definition: brep_debug.cpp:634
int brep_loop_info(struct brep_specific *bs, struct bu_vls *vls, int li)
bool near_equal(double first, double second)
Definition: brep.cpp:1814
int brep_conversion_tree(const struct db_i *dbip, const union tree *oldtree, union tree *newtree, const char *suffix, struct rt_wdb *wdbp, fastf_t local2mm)
#define M_COLOR_PLOT(c)
Definition: brep_debug.h:96
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
void plotsurfaceleafs(SurfaceTree *surf)
Definition: brep_debug.cpp:128
int brep_trim_direction_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index, int plotres)
Definition: vls.h:56
HIDDEN const point_t delta
Definition: sh_prj.c:618
double fastf_t
Definition: defines.h:300
int brep_surface_cv_plot(struct bu_vls *vls, struct brep_specific *bs, struct rt_brep_internal *, struct bn_vlblock *vbp, int index)
#define OP_UNION
Binary: L union R.
Definition: raytrace.h:1127
void plottrimdirection(ON_BrepFace &face, struct bn_vlblock *vbp, int plotres)
Definition: brep_debug.cpp:517
#define OP_NOT
Unary: not L.
Definition: raytrace.h:1134
double para
nearly 1
Definition: tol.h:76
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
void rt_comb_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol, const struct db_i *dbip)
Definition: comb_brep.cpp:123
int brep_intersect_point_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j)
Definition: color.c:50
#define bu_strlcat(dst, src, size)
Definition: str.h:50
int brep_curve_info(struct brep_specific *bs, struct bu_vls *vls, int ci)
#define BN_VLIST_POINT_DRAW
Draw a single point.
Definition: vlist.h:94
int brep_intersect_surface_surface(struct rt_db_internal *intern1, struct rt_db_internal *intern2, int i, int j, struct bn_vlblock *vbp)
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126