1 #ifndef NOTCL
2 
3 #include <mystdlib.h>
4 
5 #include <meshing.hpp>
6 
7 // #include "incvis.hpp"
8 
9 
10 #include <visual.hpp>
11 
12 
13 namespace netgen
14 {
15   // #include "meshdoc.hpp"
16 
17 
18 MeshDoctorParameters meshdoctor;
19 VisualSceneMeshDoctor vsmeshdoc;
20 
21 extern AutoPtr<Mesh> mesh;
22 
Ng_MeshDoctor(ClientData clientData,Tcl_Interp * interp,int argc,tcl_const char * argv[])23   int Ng_MeshDoctor (ClientData clientData,
24 		     Tcl_Interp * interp,
25 		     int argc, tcl_const char *argv[])
26 {
27   cout << "Mesh Doctor:" << endl;
28   int i;
29   for (i = 0; i < argc; i++)
30     cout << argv[i] << " ";
31   cout << endl;
32 
33   meshdoctor.active =
34       atoi (Tcl_GetVar (interp, "::meshdoctor.active", 0));
35 
36 
37   if (argc >= 2)
38     {
39       if (strcmp (argv[1], "markedgedist") == 0)
40 	{
41 	  vsmeshdoc.SetMarkEdgeDist (atoi (argv[2]));
42 	}
43 
44       if (strcmp (argv[1], "deletemarkedsegments") == 0)
45 	{
46 	  for (i = 1; i <= mesh->GetNSeg(); i++)
47 	    if (vsmeshdoc.IsSegmentMarked (i))
48 	      mesh->DeleteSegment (i);
49 
50 	  //	  for (i = 1; i <= mesh->GetNSE(); i++)
51 	  //	    mesh->SurfaceElement(i).SetIndex (1);
52 	  mesh->Compress();
53 	}
54     }
55 
56 
57   vsmeshdoc.UpdateTables ();
58   vsmeshdoc.BuildScene();
59   return TCL_OK;
60 }
61 
62 
63 
64 
65 
VisualSceneMeshDoctor()66 VisualSceneMeshDoctor :: VisualSceneMeshDoctor ()
67   : VisualScene()
68 {
69   filledlist = 0;
70   outlinelist = 0;
71   edgelist = 0;
72   selelement = 0;
73   locpi = 1;
74   selpoint = 0;
75   selpoint2 = 0;
76   markedgedist = 1;
77 
78   UpdateTables ();
79 }
80 
~VisualSceneMeshDoctor()81 VisualSceneMeshDoctor :: ~VisualSceneMeshDoctor ()
82 {
83   ;
84 }
85 
DrawScene()86 void VisualSceneMeshDoctor :: DrawScene ()
87 {
88   if (!mesh) return;
89 
90   int hchval = mesh->GetNP() + mesh->GetNE() + mesh->GetNSE();
91   if (changeval != hchval)
92     {
93       changeval = hchval;
94       BuildScene();
95     }
96 
97 
98   glClearColor(backcolor, backcolor, backcolor, 1.0);
99   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
100 
101   glEnable (GL_COLOR_MATERIAL);
102   glColor3f (1.0f, 1.0f, 1.0f);
103   glLineWidth (1.0f);
104 
105   SetLight();
106 
107   glPushMatrix();
108   glMultMatrixf (transformationmat);
109 
110   glInitNames ();
111   glPushName (0);
112 
113   glPolygonOffset (1, 1);
114   glEnable (GL_POLYGON_OFFSET_FILL);
115 
116   SetClippingPlane ();
117 
118   if (vispar.drawfilledtrigs)
119     glCallList (filledlist);
120 
121   glDisable (GL_POLYGON_OFFSET_FILL);
122 
123   if (vispar.drawoutline)
124     glCallList (outlinelist);
125 
126   glPolygonOffset (-1, -1);
127   glEnable (GL_POLYGON_OFFSET_LINE);
128 
129   if (vispar.drawedges)
130     glCallList (edgelist);
131 
132 
133   glDisable (GL_POLYGON_OFFSET_LINE);
134 
135 
136 
137   glPopName();
138 
139   if (selpoint > 0 && selpoint <= mesh->GetNP())
140     {
141       GLfloat matcolblue[] = { 0, 0, 1, 1 };
142 
143       glPointSize (10);
144       glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolblue);
145       glBegin (GL_POINTS);
146 
147       const Point3d p = mesh->Point(selpoint);
148       glVertex3f (p.X(), p.Y(), p.Z());
149       glEnd();
150     }
151 
152   glDisable(GL_CLIP_PLANE0);
153 
154 
155   glPopMatrix();
156   glFinish();
157 }
158 
159 
160 
161 
BuildScene(int zoomall)162 void VisualSceneMeshDoctor :: BuildScene (int zoomall)
163 {
164   int i, j;
165 
166 
167   if (zoomall)
168     {
169       Point3d pmin, pmax;
170       mesh->GetBox (pmin, pmax, -1);
171 
172       if (vispar.centerpoint)
173 	center = mesh->Point (vispar.centerpoint);
174       else
175 	center = Center (pmin, pmax);
176 
177       rad = 0.5 * Dist (pmin, pmax);
178 
179       glEnable (GL_NORMALIZE);
180 
181       CalcTransformationMatrices();
182     }
183 
184 
185 
186 
187   if (filledlist)
188     {
189       glDeleteLists (filledlist, 1);
190       glDeleteLists (outlinelist, 1);
191       glDeleteLists (edgelist, 1);
192     }
193 
194 
195   filledlist = glGenLists (1);
196   glNewList (filledlist, GL_COMPILE);
197 
198   glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
199 
200   glLineWidth (1.0f);
201 
202   glDisable (GL_COLOR_MATERIAL);
203 
204   for (i = 1; i <= mesh->GetNSE(); i++)
205     {
206       glLoadName (i);
207 
208       // copy to be thread-safe
209       Element2d el = mesh->SurfaceElement (i);
210 
211       int drawel = 1;
212       for (j = 1; j <= el.GetNP(); j++)
213 	{
214 	  if (!el.PNum(j))
215 	    drawel = 0;
216 	}
217 
218       if (!drawel)
219 	continue;
220 
221       GLfloat matcol[] = { 0, 1, 0, 1 };
222       GLfloat matcolsel[] = { 1, 0, 0, 1 };
223 
224       if (i == selelement)
225 	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcolsel);
226       else
227 	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcol);
228 
229       if (el.GetNP() == 3)
230 	{
231 	  glBegin (GL_TRIANGLES);
232 
233 	  const Point3d & lp1 = mesh->Point (el.PNum(1));
234 	  const Point3d & lp2 = mesh->Point (el.PNum(2));
235 	  const Point3d & lp3 = mesh->Point (el.PNum(3));
236 	  Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3));
237 	  n /= (n.Length()+1e-12);
238 	  glNormal3d (n.X(), n.Y(), n.Z());
239 
240 	  if (!vispar.colormeshsize)
241 	    {
242 	      glVertex3d (lp1.X(), lp1.Y(), lp1.Z());
243 	      glVertex3d (lp2.X(), lp2.Y(), lp2.Z());
244 	      glVertex3d (lp3.X(), lp3.Y(), lp3.Z());
245 	    }
246 	  else
247 	    {
248 	      double h1 = mesh->GetH (lp1);
249 	      double h2 = mesh->GetH (lp2);
250 	      double h3 = mesh->GetH (lp3);
251 
252 	      SetOpenGlColor  (h1, 0.1, 10);
253 	      glVertex3d (lp1.X(), lp1.Y(), lp1.Z());
254 
255 	      SetOpenGlColor  (h2, 0.1, 10);
256 	      glVertex3d (lp2.X(), lp2.Y(), lp2.Z());
257 
258 	      SetOpenGlColor  (h3, 0.1, 10);
259 	      glVertex3d (lp3.X(), lp3.Y(), lp3.Z());
260 	    }
261 	  glEnd();
262 	}
263       else if (el.GetNP() == 4)
264 	{
265 	  glBegin (GL_QUADS);
266 
267 	  const Point3d & lp1 = mesh->Point (el.PNum(1));
268 	  const Point3d & lp2 = mesh->Point (el.PNum(2));
269 	  const Point3d & lp3 = mesh->Point (el.PNum(4));
270 	  const Point3d & lp4 = mesh->Point (el.PNum(3));
271 	  Vec3d n = Cross (Vec3d (lp1, lp2),
272 			   Vec3d (lp1, Center (lp3, lp4)));
273 	  n /= (n.Length()+1e-12);
274 	  glNormal3d (n.X(), n.Y(), n.Z());
275 	  glVertex3d (lp1.X(), lp1.Y(), lp1.Z());
276 	  glVertex3d (lp2.X(), lp2.Y(), lp2.Z());
277 	  glVertex3d (lp4.X(), lp4.Y(), lp4.Z());
278 	  glVertex3d (lp3.X(), lp3.Y(), lp3.Z());
279 	  glEnd();
280 	}
281       else if (el.GetNP() == 6)
282 	{
283 	  glBegin (GL_TRIANGLES);
284 	  static int trigs[4][3] = {
285 	    { 1, 6, 5 },
286 	    { 2, 4, 6 },
287 	    { 3, 5, 4 },
288 	    { 4, 5, 6 } };
289 
290 	  for (j = 0; j < 4; j++)
291 	    {
292 	      const Point3d & lp1 = mesh->Point (el.PNum(trigs[j][0]));
293 	      const Point3d & lp2 = mesh->Point (el.PNum(trigs[j][1]));
294 	      const Point3d & lp3 = mesh->Point (el.PNum(trigs[j][2]));
295 	      Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3));
296 	      n /= (n.Length() + 1e-12);
297 	      glNormal3d (n.X(), n.Y(), n.Z());
298 	      glVertex3d (lp1.X(), lp1.Y(), lp1.Z());
299 	      glVertex3d (lp2.X(), lp2.Y(), lp2.Z());
300 	      glVertex3d (lp3.X(), lp3.Y(), lp3.Z());
301 	    }
302 	  glEnd();
303 	}
304     }
305   glLoadName (0);
306 
307   glEndList ();
308 
309 
310 
311   outlinelist = glGenLists (1);
312   glNewList (outlinelist, GL_COMPILE);
313 
314   glLineWidth (1.0f);
315   glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
316 
317   glColor3f (0.0f, 0.0f, 0.0f);
318   glEnable (GL_COLOR_MATERIAL);
319 
320   for (i = 1; i <= mesh->GetNSE(); i++)
321     {
322       Element2d el = mesh->SurfaceElement(i);
323 
324       int drawel = 1;
325       for (j = 1; j <= el.GetNP(); j++)
326 	{
327 	  if (!el.PNum(j))
328 	    drawel = 0;
329 	}
330 
331       if (!drawel)
332 	continue;
333 
334 
335       if (el.GetNP() == 3)
336 	{
337 	  glBegin (GL_TRIANGLES);
338 
339 	  const Point3d & lp1 = mesh->Point (el.PNum(1));
340 	  const Point3d & lp2 = mesh->Point (el.PNum(2));
341 	  const Point3d & lp3 = mesh->Point (el.PNum(3));
342 	  Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3));
343 	  n /= (n.Length() + 1e-12);
344 	  glNormal3d (n.X(), n.Y(), n.Z());
345 	  glVertex3d (lp1.X(), lp1.Y(), lp1.Z());
346 	  glVertex3d (lp2.X(), lp2.Y(), lp2.Z());
347 	  glVertex3d (lp3.X(), lp3.Y(), lp3.Z());
348 	  glEnd();
349 	}
350       else if (el.GetNP() == 4)
351 	{
352 	  glBegin (GL_QUADS);
353 
354 	  const Point3d & lp1 = mesh->Point (el.PNum(1));
355 	  const Point3d & lp2 = mesh->Point (el.PNum(2));
356 	  const Point3d & lp3 = mesh->Point (el.PNum(4));
357 	  const Point3d & lp4 = mesh->Point (el.PNum(3));
358 	  Vec3d n = Cross (Vec3d (lp1, lp2),
359 			   Vec3d (lp1, Center (lp3, lp4)));
360 	  n /= (n.Length() + 1e-12);
361 	  glNormal3d (n.X(), n.Y(), n.Z());
362 	  glVertex3d (lp1.X(), lp1.Y(), lp1.Z());
363 	  glVertex3d (lp2.X(), lp2.Y(), lp2.Z());
364 	  glVertex3d (lp4.X(), lp4.Y(), lp4.Z());
365 	  glVertex3d (lp3.X(), lp3.Y(), lp3.Z());
366 	  glEnd();
367 	}
368       else if (el.GetNP() == 6)
369 	{
370 	  glBegin (GL_LINES);
371 
372 	  const Point3d & lp1 = mesh->Point (el.PNum(1));
373 	  const Point3d & lp2 = mesh->Point (el.PNum(2));
374 	  const Point3d & lp3 = mesh->Point (el.PNum(3));
375 	  const Point3d & lp4 = mesh->Point (el.PNum(4));
376 	  const Point3d & lp5 = mesh->Point (el.PNum(5));
377 	  const Point3d & lp6 = mesh->Point (el.PNum(6));
378 
379 	  Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3));
380 	  n /= (n.Length()+1e-12);
381 	  glNormal3d (n.X(), n.Y(), n.Z());
382 
383 	  glVertex3d (lp1.X(), lp1.Y(), lp1.Z());
384 	  glVertex3d (lp6.X(), lp6.Y(), lp6.Z());
385 	  glVertex3d (lp2.X(), lp2.Y(), lp2.Z());
386 	  glVertex3d (lp6.X(), lp6.Y(), lp6.Z());
387 
388 	  glVertex3d (lp1.X(), lp1.Y(), lp1.Z());
389 	  glVertex3d (lp5.X(), lp5.Y(), lp5.Z());
390 	  glVertex3d (lp3.X(), lp3.Y(), lp3.Z());
391 	  glVertex3d (lp5.X(), lp5.Y(), lp5.Z());
392 
393 	  glVertex3d (lp2.X(), lp2.Y(), lp2.Z());
394 	  glVertex3d (lp4.X(), lp4.Y(), lp4.Z());
395 	  glVertex3d (lp3.X(), lp3.Y(), lp3.Z());
396 	  glVertex3d (lp4.X(), lp4.Y(), lp4.Z());
397 	  glEnd();
398 	}
399     }
400   glLoadName (0);
401   glEndList ();
402 
403 
404 
405 
406 
407   edgelist = glGenLists (1);
408   glNewList (edgelist, GL_COMPILE);
409 
410   glDisable (GL_COLOR_MATERIAL);
411 
412   GLfloat matcoledge[] = { 0, 0, 1, 1 };
413   GLfloat matcolseledge[] = { 1, 0, 1, 1 };
414 
415   glLineWidth (2.0f);
416 
417   for (i = 1; i <= mesh->GetNSeg(); i++)
418     {
419       const Segment & seg = mesh->LineSegment(i);
420       const Point3d & p1 = mesh->Point(seg[0]);
421       const Point3d & p2 = mesh->Point(seg[1]);
422 
423       if (edgedist.Get(seg[0]) <= markedgedist &&
424 	  edgedist.Get(seg[1]) <= markedgedist)
425 	{
426 	  glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
427 			matcolseledge);
428 	  glLineWidth (4.0f);
429 	}
430       else
431 	{
432 	  glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
433 			matcoledge);
434 	  glLineWidth (2.0f);
435 	}
436       glBegin (GL_LINES);
437       glVertex3f (p1.X(), p1.Y(), p1.Z());
438       glVertex3f (p2.X(), p2.Y(), p2.Z());
439       glEnd();
440     }
441 
442   glLineWidth (1.0f);
443   glEndList ();
444 }
445 
446 
447 
448 
MouseDblClick(int px,int py)449 void VisualSceneMeshDoctor :: MouseDblClick (int px, int py)
450 {
451   cout << "dblclick: " << px << " - " << py << endl;
452 
453   int i, hits;
454 
455   // select surface triangle by mouse click
456   GLuint selbuf[10000];
457   glSelectBuffer (10000, selbuf);
458 
459 
460   glRenderMode (GL_SELECT);
461 
462   GLint viewport[4];
463   glGetIntegerv (GL_VIEWPORT, viewport);
464 
465   glMatrixMode (GL_PROJECTION);
466   glPushMatrix();
467 
468   GLdouble projmat[16];
469   glGetDoublev (GL_PROJECTION_MATRIX, projmat);
470 
471   glLoadIdentity();
472   gluPickMatrix (px, viewport[3] - py, 1, 1, viewport);
473   glMultMatrixd (projmat);
474 
475 
476   glClearColor(backcolor, backcolor, backcolor, 1.0);
477   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
478 
479   glMatrixMode (GL_MODELVIEW);
480 
481   glPushMatrix();
482   glMultMatrixf (transformationmat);
483 
484   glInitNames();
485   glPushName (1);
486 
487   glPolygonOffset (1, 1);
488   glEnable (GL_POLYGON_OFFSET_FILL);
489 
490   glCallList (filledlist);
491 
492   glDisable (GL_POLYGON_OFFSET_FILL);
493 
494   glPopName();
495 
496   glMatrixMode (GL_PROJECTION);
497   glPopMatrix();
498 
499   glMatrixMode (GL_MODELVIEW);
500   glPopMatrix();
501 
502   glFlush();
503 
504 
505   hits = glRenderMode (GL_RENDER);
506 
507   cout << "hits = " << hits << endl;
508 
509   int minname = 0;
510   GLuint mindepth = 0;
511   for (i = 0; i < hits; i++)
512     {
513       int curname = selbuf[4*i+3];
514       GLuint curdepth = selbuf[4*i+1];
515 
516       if (curname &&
517 	  (curdepth < mindepth || !minname))
518 	{
519 	  mindepth = curdepth;
520 	  minname = curname;
521 	}
522     }
523 
524   cout << "clicked element: " << minname << endl;
525 
526   ClickElement (minname);
527 
528   BuildScene ();
529 }
530 
531 
532 
533 
SetMarkEdgeDist(int dist)534 void VisualSceneMeshDoctor :: SetMarkEdgeDist (int dist)
535 {
536   markedgedist = dist;
537   BuildScene();
538 }
539 
ClickElement(int elnr)540 void VisualSceneMeshDoctor :: ClickElement (int elnr)
541 {
542   selelement = elnr;
543 
544   int oldlocpi = locpi;
545   locpi = locpi % 3 + 1;
546 
547   if (selelement > 0 && selelement <= mesh->GetNSE())
548     {
549       selpoint = mesh->SurfaceElement(selelement).PNum(locpi);
550       selpoint2 = mesh->SurfaceElement(selelement).PNum(oldlocpi);
551       cout << "selpts = " << selpoint << ", " << selpoint2 << endl;
552     }
553 
554   UpdateTables();
555 }
556 
557 
UpdateTables()558 void VisualSceneMeshDoctor :: UpdateTables ()
559 {
560   if (!mesh) return;
561 
562   edgedist.SetSize(mesh->GetNP());
563   int i, changed;
564 
565   for (i = 1; i <= mesh->GetNP(); i++)
566     edgedist.Elem(i) = 10000;
567 
568   for (i = 1; i <= mesh->GetNSeg(); i++)
569     {
570       const Segment & seg = mesh->LineSegment(i);
571       if ( (seg[0] == selpoint && seg[1] == selpoint2) ||
572            (seg[1] == selpoint && seg[0] == selpoint2) )
573 	{
574 	  edgedist.Elem(selpoint) = 1;
575 	  edgedist.Elem(selpoint2) = 1;
576 	}
577     }
578 
579   do
580     {
581       changed = 0;
582 
583       for (i = 1; i <= mesh->GetNSeg(); i++)
584 	{
585 	  const Segment & seg = mesh->LineSegment(i);
586 
587 	  int edist = min2 (edgedist.Get(seg[0]), edgedist.Get(seg[1]));
588 	  edist++;
589 
590 	  if (edgedist.Get(seg[0]) > edist)
591 	    {
592 	      edgedist.Elem(seg[0]) = edist;
593 	      changed = 1;
594 	    }
595 	  if (edgedist.Get(seg[1]) > edist)
596 	    {
597 	      edgedist.Elem(seg[1]) = edist;
598 	      changed = 1;
599 	    }
600 	}
601     }
602   while (changed);
603 }
604 
IsSegmentMarked(int segnr) const605 int VisualSceneMeshDoctor :: IsSegmentMarked (int segnr) const
606 {
607   const Segment & seg = mesh->LineSegment(segnr);
608   return (edgedist.Get(seg[0]) <= markedgedist &&
609 	  edgedist.Get(seg[1]) <= markedgedist);
610 }
611 }
612 
613 
614 #endif // NOTCL
615