1 // Gmsh - Copyright (C) 1997-2021 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5
6 #include <stdlib.h>
7 #include <FL/Fl_Tabs.H>
8 #include <FL/Fl_Return_Button.H>
9 #include "FlGui.h"
10 #include "drawContext.h"
11 #include "contextWindow.h"
12 #include "paletteWindow.h"
13 #include "graphicWindow.h"
14 #include "openglWindow.h"
15 #include "Parser.h"
16 #include "GModel.h"
17 #ifdef Convex // can be defined by Xlib
18 #undef Convex
19 #endif
20 #include "GModelIO_OCC.h"
21 #include "scriptStringInterface.h"
22 #include "OpenFile.h"
23 #include "Context.h"
24 #include "Options.h"
25 #include "MallocUtils.h"
26 #include "StringUtils.h"
27 #include "Geo.h"
28 #include "VertexArray.h"
29 #include "mathEvaluator.h"
30
getval(const char * str,double & val)31 static bool getval(const char *str, double &val)
32 {
33 std::vector<std::string> var;
34 std::vector<double> valVar;
35
36 // we should probably use the actual .geo parser instead...
37 for(auto it = gmsh_yysymbols.begin(); it != gmsh_yysymbols.end(); it++) {
38 if(it->second.value.size() == 1) {
39 var.push_back(it->first);
40 valVar.push_back(it->second.value[0]);
41 }
42 }
43
44 std::vector<std::string> expr(1);
45 expr[0] = str;
46 std::vector<double> res(1);
47 mathEvaluator f(expr, var);
48 if(expr.empty()) return false;
49 if(!f.eval(valVar, res)) return false;
50 val = res[0];
51 return true;
52 }
53
draw_stl(std::vector<SPoint3> & vertices,std::vector<SVector3> & normals,std::vector<int> & triangles)54 static void draw_stl(std::vector<SPoint3> &vertices,
55 std::vector<SVector3> &normals,
56 std::vector<int> &triangles)
57 {
58 GLint mode[2];
59 glGetIntegerv(GL_POLYGON_MODE, mode);
60 if(CTX::instance()->geom.surfaceType == 1)
61 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
62 else
63 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
64 glEnable(GL_LIGHTING);
65 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
66 glColor4ubv((GLubyte *)&CTX::instance()->color.geom.highlight[0]);
67
68 VertexArray va(3, triangles.size());
69 for(std::size_t i = 0; i < triangles.size(); i += 3) {
70 SPoint3 p1 = vertices[triangles[i]];
71 SPoint3 p2 = vertices[triangles[i + 1]];
72 SPoint3 p3 = vertices[triangles[i + 2]];
73 SVector3 n1 = normals[triangles[i]];
74 SVector3 n2 = normals[triangles[i + 1]];
75 SVector3 n3 = normals[triangles[i + 2]];
76 double x[3] = {p1.x(), p2.x(), p3.x()};
77 double y[3] = {p1.y(), p2.y(), p3.y()};
78 double z[3] = {p1.z(), p2.z(), p3.z()};
79 SVector3 nn[3] = {n1, n2, n3};
80 va.add(x, y, z, nn);
81 }
82 va.finalize();
83
84 glVertexPointer(3, GL_FLOAT, 0, va.getVertexArray());
85 glEnableClientState(GL_VERTEX_ARRAY);
86 glNormalPointer(NORMAL_GLTYPE, 0, va.getNormalArray());
87 glEnableClientState(GL_NORMAL_ARRAY);
88 glDisableClientState(GL_COLOR_ARRAY);
89 glDrawArrays(GL_TRIANGLES, 0, va.getNumVertices());
90 glDisableClientState(GL_VERTEX_ARRAY);
91 glDisableClientState(GL_NORMAL_ARRAY);
92
93 glDisable(GL_LIGHTING);
94 glPolygonMode(GL_FRONT_AND_BACK, mode[1]);
95 }
96
elementary_add_parameter_cb(Fl_Widget * w,void * data)97 static void elementary_add_parameter_cb(Fl_Widget *w, void *data)
98 {
99 scriptAddParameter(FlGui::instance()->elementaryContext->input[0]->value(),
100 FlGui::instance()->elementaryContext->input[1]->value(),
101 FlGui::instance()->elementaryContext->input[2]->value(),
102 FlGui::instance()->elementaryContext->input[3]->value(),
103 GModel::current()->getFileName());
104 FlGui::instance()->resetVisibility();
105 FlGui::instance()->rebuildTree(true);
106 }
107
elementary_draw_point_cb(Fl_Widget * w,void * data)108 static void elementary_draw_point_cb(Fl_Widget *w, void *data)
109 {
110 if(data) return; // we are here from do_callback()
111 double x, y, z;
112 if(!getval(FlGui::instance()->elementaryContext->input[4]->value(), x))
113 return;
114 if(!getval(FlGui::instance()->elementaryContext->input[5]->value(), y))
115 return;
116 if(!getval(FlGui::instance()->elementaryContext->input[6]->value(), z))
117 return;
118 FlGui::instance()->getCurrentOpenglWindow()->setPoint(x, y, z);
119 drawContext::global()->draw();
120 }
121
elementary_add_point_cb(Fl_Widget * w,void * data)122 static void elementary_add_point_cb(Fl_Widget *w, void *data)
123 {
124 scriptAddPoint(GModel::current()->getFileName(),
125 FlGui::instance()->elementaryContext->input[4]->value(),
126 FlGui::instance()->elementaryContext->input[5]->value(),
127 FlGui::instance()->elementaryContext->input[6]->value(),
128 FlGui::instance()->elementaryContext->input[7]->value());
129 FlGui::instance()->resetVisibility();
130 GModel::current()->setSelection(0);
131 SetBoundingBox();
132 drawContext::global()->draw();
133 }
134
draw_circle(void * context)135 static void draw_circle(void *context)
136 {
137 if(!GModel::current()->getOCCInternals())
138 GModel::current()->createOCCInternals();
139 double xc, yc, zc, r, angle1, angle2;
140 if(!getval(FlGui::instance()->elementaryContext->input[8]->value(), xc))
141 return;
142 if(!getval(FlGui::instance()->elementaryContext->input[9]->value(), yc))
143 return;
144 if(!getval(FlGui::instance()->elementaryContext->input[10]->value(), zc))
145 return;
146 if(!getval(FlGui::instance()->elementaryContext->input[11]->value(), r))
147 return;
148 if(!getval(FlGui::instance()->elementaryContext->input[12]->value(), angle1))
149 return;
150 if(!getval(FlGui::instance()->elementaryContext->input[13]->value(), angle2))
151 return;
152
153 if(angle2 <= angle1) return;
154 glColor4ubv((GLubyte *)&CTX::instance()->color.geom.highlight[0]);
155 glBegin(GL_LINE_STRIP);
156 const int N = 30;
157 for(int i = 0; i < N; i++) {
158 double t = angle1 + (double)i / (double)(N - 1) * (angle2 - angle1);
159 double x = xc + r * cos(t);
160 double y = yc + r * sin(t);
161 double z = zc;
162 glVertex3d(x, y, z);
163 }
164 glEnd();
165 }
166
elementary_draw_circle_cb(Fl_Widget * w,void * data)167 static void elementary_draw_circle_cb(Fl_Widget *w, void *data)
168 {
169 drawContext::setDrawGeomTransientFunction(draw_circle);
170 if(!data) drawContext::global()->draw();
171 }
172
elementary_add_circle_cb(Fl_Widget * w,void * data)173 static void elementary_add_circle_cb(Fl_Widget *w, void *data)
174 {
175 scriptAddCircle(GModel::current()->getFileName(),
176 FlGui::instance()->elementaryContext->input[8]->value(),
177 FlGui::instance()->elementaryContext->input[9]->value(),
178 FlGui::instance()->elementaryContext->input[10]->value(),
179 FlGui::instance()->elementaryContext->input[11]->value(),
180 FlGui::instance()->elementaryContext->input[12]->value(),
181 FlGui::instance()->elementaryContext->input[13]->value());
182 FlGui::instance()->resetVisibility();
183 GModel::current()->setSelection(0);
184 SetBoundingBox();
185 drawContext::global()->draw();
186 }
187
draw_ellipse(void * context)188 static void draw_ellipse(void *context)
189 {
190 if(!GModel::current()->getOCCInternals())
191 GModel::current()->createOCCInternals();
192 double xc, yc, zc, rx, ry, angle1, angle2;
193 if(!getval(FlGui::instance()->elementaryContext->input[14]->value(), xc))
194 return;
195 if(!getval(FlGui::instance()->elementaryContext->input[15]->value(), yc))
196 return;
197 if(!getval(FlGui::instance()->elementaryContext->input[16]->value(), zc))
198 return;
199 if(!getval(FlGui::instance()->elementaryContext->input[17]->value(), rx))
200 return;
201 if(!getval(FlGui::instance()->elementaryContext->input[18]->value(), ry))
202 return;
203 if(!getval(FlGui::instance()->elementaryContext->input[19]->value(), angle1))
204 return;
205 if(!getval(FlGui::instance()->elementaryContext->input[20]->value(), angle2))
206 return;
207 if(angle2 <= angle1) return;
208 glColor4ubv((GLubyte *)&CTX::instance()->color.geom.highlight[0]);
209 glBegin(GL_LINE_STRIP);
210 const int N = 30;
211 for(int i = 0; i < N; i++) {
212 double t = angle1 + (double)i / (double)(N - 1) * (angle2 - angle1);
213 double x = xc + rx * cos(t);
214 double y = yc + ry * sin(t);
215 double z = zc;
216 glVertex3d(x, y, z);
217 }
218 glEnd();
219 }
220
elementary_draw_ellipse_cb(Fl_Widget * w,void * data)221 static void elementary_draw_ellipse_cb(Fl_Widget *w, void *data)
222 {
223 drawContext::setDrawGeomTransientFunction(draw_ellipse);
224 if(!data) drawContext::global()->draw();
225 }
226
elementary_add_ellipse_cb(Fl_Widget * w,void * data)227 static void elementary_add_ellipse_cb(Fl_Widget *w, void *data)
228 {
229 scriptAddEllipse(GModel::current()->getFileName(),
230 FlGui::instance()->elementaryContext->input[14]->value(),
231 FlGui::instance()->elementaryContext->input[15]->value(),
232 FlGui::instance()->elementaryContext->input[16]->value(),
233 FlGui::instance()->elementaryContext->input[17]->value(),
234 FlGui::instance()->elementaryContext->input[18]->value(),
235 FlGui::instance()->elementaryContext->input[19]->value(),
236 FlGui::instance()->elementaryContext->input[20]->value());
237 FlGui::instance()->resetVisibility();
238 GModel::current()->setSelection(0);
239 SetBoundingBox();
240 drawContext::global()->draw();
241 }
242
draw_disk(void * context)243 static void draw_disk(void *context)
244 {
245 if(!GModel::current()->getOCCInternals())
246 GModel::current()->createOCCInternals();
247 double xc, yc, zc, rx, ry;
248 if(!getval(FlGui::instance()->elementaryContext->input[21]->value(), xc))
249 return;
250 if(!getval(FlGui::instance()->elementaryContext->input[22]->value(), yc))
251 return;
252 if(!getval(FlGui::instance()->elementaryContext->input[23]->value(), zc))
253 return;
254 if(!getval(FlGui::instance()->elementaryContext->input[24]->value(), rx))
255 return;
256 if(!getval(FlGui::instance()->elementaryContext->input[25]->value(), ry))
257 return;
258 std::vector<SPoint3> vertices;
259 std::vector<SVector3> normals;
260 std::vector<int> triangles;
261 if(!GModel::current()->getOCCInternals()->makeDiskSTL(
262 xc, yc, zc, rx, ry, vertices, normals, triangles))
263 return;
264 draw_stl(vertices, normals, triangles);
265 }
266
elementary_draw_disk_cb(Fl_Widget * w,void * data)267 static void elementary_draw_disk_cb(Fl_Widget *w, void *data)
268 {
269 drawContext::setDrawGeomTransientFunction(draw_disk);
270 if(!data) drawContext::global()->draw();
271 }
272
elementary_add_disk_cb(Fl_Widget * w,void * data)273 static void elementary_add_disk_cb(Fl_Widget *w, void *data)
274 {
275 scriptAddDisk(GModel::current()->getFileName(),
276 FlGui::instance()->elementaryContext->input[21]->value(),
277 FlGui::instance()->elementaryContext->input[22]->value(),
278 FlGui::instance()->elementaryContext->input[23]->value(),
279 FlGui::instance()->elementaryContext->input[24]->value(),
280 FlGui::instance()->elementaryContext->input[25]->value());
281 FlGui::instance()->resetVisibility();
282 GModel::current()->setSelection(0);
283 SetBoundingBox();
284 drawContext::global()->draw();
285 }
286
draw_rectangle(void * context)287 static void draw_rectangle(void *context)
288 {
289 if(!GModel::current()->getOCCInternals())
290 GModel::current()->createOCCInternals();
291 double x, y, z, dx, dy, r;
292 if(!getval(FlGui::instance()->elementaryContext->input[26]->value(), x))
293 return;
294 if(!getval(FlGui::instance()->elementaryContext->input[27]->value(), y))
295 return;
296 if(!getval(FlGui::instance()->elementaryContext->input[28]->value(), z))
297 return;
298 if(!getval(FlGui::instance()->elementaryContext->input[29]->value(), dx))
299 return;
300 if(!getval(FlGui::instance()->elementaryContext->input[30]->value(), dy))
301 return;
302 if(!getval(FlGui::instance()->elementaryContext->input[31]->value(), r))
303 return;
304 std::vector<SPoint3> vertices;
305 std::vector<SVector3> normals;
306 std::vector<int> triangles;
307 if(!GModel::current()->getOCCInternals()->makeRectangleSTL(
308 x, y, z, dx, dy, r, vertices, normals, triangles))
309 return;
310 draw_stl(vertices, normals, triangles);
311 }
312
elementary_draw_rectangle_cb(Fl_Widget * w,void * data)313 static void elementary_draw_rectangle_cb(Fl_Widget *w, void *data)
314 {
315 drawContext::setDrawGeomTransientFunction(draw_rectangle);
316 if(!data) drawContext::global()->draw();
317 }
318
elementary_add_rectangle_cb(Fl_Widget * w,void * data)319 static void elementary_add_rectangle_cb(Fl_Widget *w, void *data)
320 {
321 scriptAddRectangle(GModel::current()->getFileName(),
322 FlGui::instance()->elementaryContext->input[26]->value(),
323 FlGui::instance()->elementaryContext->input[27]->value(),
324 FlGui::instance()->elementaryContext->input[28]->value(),
325 FlGui::instance()->elementaryContext->input[29]->value(),
326 FlGui::instance()->elementaryContext->input[30]->value(),
327 FlGui::instance()->elementaryContext->input[31]->value());
328 FlGui::instance()->resetVisibility();
329 GModel::current()->setSelection(0);
330 SetBoundingBox();
331 drawContext::global()->draw();
332 }
333
draw_sphere(void * context)334 static void draw_sphere(void *context)
335 {
336 if(!GModel::current()->getOCCInternals())
337 GModel::current()->createOCCInternals();
338 double xc, yc, zc, r, angle1, angle2, angle3;
339 if(!getval(FlGui::instance()->elementaryContext->input[32]->value(), xc))
340 return;
341 if(!getval(FlGui::instance()->elementaryContext->input[33]->value(), yc))
342 return;
343 if(!getval(FlGui::instance()->elementaryContext->input[34]->value(), zc))
344 return;
345 if(!getval(FlGui::instance()->elementaryContext->input[35]->value(), r))
346 return;
347 if(!getval(FlGui::instance()->elementaryContext->input[36]->value(), angle1))
348 return;
349 if(!getval(FlGui::instance()->elementaryContext->input[37]->value(), angle2))
350 return;
351 if(!getval(FlGui::instance()->elementaryContext->input[38]->value(), angle3))
352 return;
353 std::vector<SPoint3> vertices;
354 std::vector<SVector3> normals;
355 std::vector<int> triangles;
356 if(!GModel::current()->getOCCInternals()->makeSphereSTL(
357 xc, yc, zc, r, angle1, angle2, angle3, vertices, normals, triangles))
358 return;
359 draw_stl(vertices, normals, triangles);
360 }
361
elementary_draw_sphere_cb(Fl_Widget * w,void * data)362 static void elementary_draw_sphere_cb(Fl_Widget *w, void *data)
363 {
364 drawContext::setDrawGeomTransientFunction(draw_sphere);
365 if(!data) drawContext::global()->draw();
366 }
367
elementary_add_sphere_cb(Fl_Widget * w,void * data)368 static void elementary_add_sphere_cb(Fl_Widget *w, void *data)
369 {
370 scriptAddSphere(GModel::current()->getFileName(),
371 FlGui::instance()->elementaryContext->input[32]->value(),
372 FlGui::instance()->elementaryContext->input[33]->value(),
373 FlGui::instance()->elementaryContext->input[34]->value(),
374 FlGui::instance()->elementaryContext->input[35]->value(),
375 FlGui::instance()->elementaryContext->input[36]->value(),
376 FlGui::instance()->elementaryContext->input[37]->value(),
377 FlGui::instance()->elementaryContext->input[38]->value());
378 FlGui::instance()->resetVisibility();
379 GModel::current()->setSelection(0);
380 drawContext::setDrawGeomTransientFunction(nullptr);
381 SetBoundingBox();
382 drawContext::global()->draw();
383 }
384
draw_cylinder(void * context)385 static void draw_cylinder(void *context)
386 {
387 if(!GModel::current()->getOCCInternals())
388 GModel::current()->createOCCInternals();
389 double xc, yc, zc, dx, dy, dz, r, angle;
390 if(!getval(FlGui::instance()->elementaryContext->input[39]->value(), xc))
391 return;
392 if(!getval(FlGui::instance()->elementaryContext->input[40]->value(), yc))
393 return;
394 if(!getval(FlGui::instance()->elementaryContext->input[41]->value(), zc))
395 return;
396 if(!getval(FlGui::instance()->elementaryContext->input[42]->value(), dx))
397 return;
398 if(!getval(FlGui::instance()->elementaryContext->input[43]->value(), dy))
399 return;
400 if(!getval(FlGui::instance()->elementaryContext->input[44]->value(), dz))
401 return;
402 if(!getval(FlGui::instance()->elementaryContext->input[45]->value(), r))
403 return;
404 if(!getval(FlGui::instance()->elementaryContext->input[46]->value(), angle))
405 return;
406 std::vector<SPoint3> vertices;
407 std::vector<SVector3> normals;
408 std::vector<int> triangles;
409 if(!GModel::current()->getOCCInternals()->makeCylinderSTL(
410 xc, yc, zc, dx, dy, dz, r, angle, vertices, normals, triangles))
411 return;
412 draw_stl(vertices, normals, triangles);
413 }
414
elementary_draw_cylinder_cb(Fl_Widget * w,void * data)415 static void elementary_draw_cylinder_cb(Fl_Widget *w, void *data)
416 {
417 drawContext::setDrawGeomTransientFunction(draw_cylinder);
418 if(!data) drawContext::global()->draw();
419 }
420
elementary_add_cylinder_cb(Fl_Widget * w,void * data)421 static void elementary_add_cylinder_cb(Fl_Widget *w, void *data)
422 {
423 scriptAddCylinder(GModel::current()->getFileName(),
424 FlGui::instance()->elementaryContext->input[39]->value(),
425 FlGui::instance()->elementaryContext->input[40]->value(),
426 FlGui::instance()->elementaryContext->input[41]->value(),
427 FlGui::instance()->elementaryContext->input[42]->value(),
428 FlGui::instance()->elementaryContext->input[43]->value(),
429 FlGui::instance()->elementaryContext->input[44]->value(),
430 FlGui::instance()->elementaryContext->input[45]->value(),
431 FlGui::instance()->elementaryContext->input[46]->value());
432 FlGui::instance()->resetVisibility();
433 GModel::current()->setSelection(0);
434 SetBoundingBox();
435 drawContext::global()->draw();
436 }
437
draw_box(void * context)438 static void draw_box(void *context)
439 {
440 if(!GModel::current()->getOCCInternals())
441 GModel::current()->createOCCInternals();
442 double x, y, z, dx, dy, dz;
443 if(!getval(FlGui::instance()->elementaryContext->input[47]->value(), x))
444 return;
445 if(!getval(FlGui::instance()->elementaryContext->input[48]->value(), y))
446 return;
447 if(!getval(FlGui::instance()->elementaryContext->input[49]->value(), z))
448 return;
449 if(!getval(FlGui::instance()->elementaryContext->input[50]->value(), dx))
450 return;
451 if(!getval(FlGui::instance()->elementaryContext->input[51]->value(), dy))
452 return;
453 if(!getval(FlGui::instance()->elementaryContext->input[52]->value(), dz))
454 return;
455 std::vector<SPoint3> vertices;
456 std::vector<SVector3> normals;
457 std::vector<int> triangles;
458 if(!GModel::current()->getOCCInternals()->makeBoxSTL(
459 x, y, z, dx, dy, dz, vertices, normals, triangles))
460 return;
461 draw_stl(vertices, normals, triangles);
462 }
463
elementary_draw_box_cb(Fl_Widget * w,void * data)464 static void elementary_draw_box_cb(Fl_Widget *w, void *data)
465 {
466 drawContext::setDrawGeomTransientFunction(draw_box);
467 if(!data) drawContext::global()->draw();
468 }
469
elementary_add_box_cb(Fl_Widget * w,void * data)470 static void elementary_add_box_cb(Fl_Widget *w, void *data)
471 {
472 scriptAddBox(GModel::current()->getFileName(),
473 FlGui::instance()->elementaryContext->input[47]->value(),
474 FlGui::instance()->elementaryContext->input[48]->value(),
475 FlGui::instance()->elementaryContext->input[49]->value(),
476 FlGui::instance()->elementaryContext->input[50]->value(),
477 FlGui::instance()->elementaryContext->input[51]->value(),
478 FlGui::instance()->elementaryContext->input[52]->value());
479 FlGui::instance()->resetVisibility();
480 GModel::current()->setSelection(0);
481 SetBoundingBox();
482 drawContext::global()->draw();
483 }
484
draw_torus(void * context)485 static void draw_torus(void *context)
486 {
487 if(!GModel::current()->getOCCInternals())
488 GModel::current()->createOCCInternals();
489 double xc, yc, zc, r1, r2, angle;
490 if(!getval(FlGui::instance()->elementaryContext->input[53]->value(), xc))
491 return;
492 if(!getval(FlGui::instance()->elementaryContext->input[54]->value(), yc))
493 return;
494 if(!getval(FlGui::instance()->elementaryContext->input[55]->value(), zc))
495 return;
496 if(!getval(FlGui::instance()->elementaryContext->input[56]->value(), r1))
497 return;
498 if(!getval(FlGui::instance()->elementaryContext->input[57]->value(), r2))
499 return;
500 if(!getval(FlGui::instance()->elementaryContext->input[58]->value(), angle))
501 return;
502 std::vector<SPoint3> vertices;
503 std::vector<SVector3> normals;
504 std::vector<int> triangles;
505 if(!GModel::current()->getOCCInternals()->makeTorusSTL(
506 xc, yc, zc, r1, r2, angle, vertices, normals, triangles))
507 return;
508 draw_stl(vertices, normals, triangles);
509 }
510
elementary_draw_torus_cb(Fl_Widget * w,void * data)511 static void elementary_draw_torus_cb(Fl_Widget *w, void *data)
512 {
513 drawContext::setDrawGeomTransientFunction(draw_torus);
514 if(!data) drawContext::global()->draw();
515 }
516
elementary_add_torus_cb(Fl_Widget * w,void * data)517 static void elementary_add_torus_cb(Fl_Widget *w, void *data)
518 {
519 scriptAddTorus(GModel::current()->getFileName(),
520 FlGui::instance()->elementaryContext->input[53]->value(),
521 FlGui::instance()->elementaryContext->input[54]->value(),
522 FlGui::instance()->elementaryContext->input[55]->value(),
523 FlGui::instance()->elementaryContext->input[56]->value(),
524 FlGui::instance()->elementaryContext->input[57]->value(),
525 FlGui::instance()->elementaryContext->input[58]->value());
526 FlGui::instance()->resetVisibility();
527 GModel::current()->setSelection(0);
528 SetBoundingBox();
529 drawContext::global()->draw();
530 }
531
draw_cone(void * context)532 static void draw_cone(void *context)
533 {
534 if(!GModel::current()->getOCCInternals())
535 GModel::current()->createOCCInternals();
536 double xc, yc, zc, dx, dy, dz, r1, r2, angle;
537 if(!getval(FlGui::instance()->elementaryContext->input[59]->value(), xc))
538 return;
539 if(!getval(FlGui::instance()->elementaryContext->input[60]->value(), yc))
540 return;
541 if(!getval(FlGui::instance()->elementaryContext->input[61]->value(), zc))
542 return;
543 if(!getval(FlGui::instance()->elementaryContext->input[62]->value(), dx))
544 return;
545 if(!getval(FlGui::instance()->elementaryContext->input[63]->value(), dy))
546 return;
547 if(!getval(FlGui::instance()->elementaryContext->input[64]->value(), dz))
548 return;
549 if(!getval(FlGui::instance()->elementaryContext->input[65]->value(), r1))
550 return;
551 if(!getval(FlGui::instance()->elementaryContext->input[66]->value(), r2))
552 return;
553 if(!getval(FlGui::instance()->elementaryContext->input[67]->value(), angle))
554 return;
555 std::vector<SPoint3> vertices;
556 std::vector<SVector3> normals;
557 std::vector<int> triangles;
558 if(!GModel::current()->getOCCInternals()->makeConeSTL(
559 xc, yc, zc, dx, dy, dz, r1, r2, angle, vertices, normals, triangles))
560 return;
561 draw_stl(vertices, normals, triangles);
562 }
563
elementary_draw_cone_cb(Fl_Widget * w,void * data)564 static void elementary_draw_cone_cb(Fl_Widget *w, void *data)
565 {
566 drawContext::setDrawGeomTransientFunction(draw_cone);
567 if(!data) drawContext::global()->draw();
568 }
569
elementary_add_cone_cb(Fl_Widget * w,void * data)570 static void elementary_add_cone_cb(Fl_Widget *w, void *data)
571 {
572 scriptAddCone(GModel::current()->getFileName(),
573 FlGui::instance()->elementaryContext->input[59]->value(),
574 FlGui::instance()->elementaryContext->input[60]->value(),
575 FlGui::instance()->elementaryContext->input[61]->value(),
576 FlGui::instance()->elementaryContext->input[62]->value(),
577 FlGui::instance()->elementaryContext->input[63]->value(),
578 FlGui::instance()->elementaryContext->input[64]->value(),
579 FlGui::instance()->elementaryContext->input[65]->value(),
580 FlGui::instance()->elementaryContext->input[66]->value(),
581 FlGui::instance()->elementaryContext->input[67]->value());
582 FlGui::instance()->resetVisibility();
583 GModel::current()->setSelection(0);
584 SetBoundingBox();
585 drawContext::global()->draw();
586 }
587
draw_wedge(void * context)588 static void draw_wedge(void *context)
589 {
590 if(!GModel::current()->getOCCInternals())
591 GModel::current()->createOCCInternals();
592 double x, y, z, dx, dy, dz, ltx;
593 if(!getval(FlGui::instance()->elementaryContext->input[68]->value(), x))
594 return;
595 if(!getval(FlGui::instance()->elementaryContext->input[69]->value(), y))
596 return;
597 if(!getval(FlGui::instance()->elementaryContext->input[70]->value(), z))
598 return;
599 if(!getval(FlGui::instance()->elementaryContext->input[71]->value(), dx))
600 return;
601 if(!getval(FlGui::instance()->elementaryContext->input[72]->value(), dy))
602 return;
603 if(!getval(FlGui::instance()->elementaryContext->input[73]->value(), dz))
604 return;
605 if(!getval(FlGui::instance()->elementaryContext->input[74]->value(), ltx))
606 return;
607 std::vector<SPoint3> vertices;
608 std::vector<SVector3> normals;
609 std::vector<int> triangles;
610 if(!GModel::current()->getOCCInternals()->makeWedgeSTL(
611 x, y, z, dx, dy, dz, ltx, vertices, normals, triangles))
612 return;
613 draw_stl(vertices, normals, triangles);
614 }
615
elementary_draw_wedge_cb(Fl_Widget * w,void * data)616 static void elementary_draw_wedge_cb(Fl_Widget *w, void *data)
617 {
618 drawContext::setDrawGeomTransientFunction(draw_wedge);
619 if(!data) drawContext::global()->draw();
620 }
621
elementary_add_wedge_cb(Fl_Widget * w,void * data)622 static void elementary_add_wedge_cb(Fl_Widget *w, void *data)
623 {
624 scriptAddWedge(GModel::current()->getFileName(),
625 FlGui::instance()->elementaryContext->input[68]->value(),
626 FlGui::instance()->elementaryContext->input[69]->value(),
627 FlGui::instance()->elementaryContext->input[70]->value(),
628 FlGui::instance()->elementaryContext->input[71]->value(),
629 FlGui::instance()->elementaryContext->input[72]->value(),
630 FlGui::instance()->elementaryContext->input[73]->value(),
631 FlGui::instance()->elementaryContext->input[74]->value());
632 FlGui::instance()->resetVisibility();
633 GModel::current()->setSelection(0);
634 SetBoundingBox();
635 drawContext::global()->draw();
636 }
637
elementary_switch_tabs_cb(Fl_Widget * w,void * data)638 static void elementary_switch_tabs_cb(Fl_Widget *w, void *data)
639 {
640 if(FlGui::instance()->elementaryContext->tab1->visible()) {
641 FlGui::instance()->elementaryContext->tab1->hide();
642 FlGui::instance()->elementaryContext->tab2->show();
643 }
644 else {
645 FlGui::instance()->elementaryContext->tab2->hide();
646 FlGui::instance()->elementaryContext->tab1->show();
647 }
648 }
649
elementary_snap_cb(Fl_Widget * w,void * data)650 static void elementary_snap_cb(Fl_Widget *w, void *data)
651 {
652 CTX::instance()->geom.snap[0] =
653 FlGui::instance()->elementaryContext->value[0]->value();
654 CTX::instance()->geom.snap[1] =
655 FlGui::instance()->elementaryContext->value[1]->value();
656 CTX::instance()->geom.snap[2] =
657 FlGui::instance()->elementaryContext->value[2]->value();
658 }
659
elementaryContextWindow(int deltaFontSize)660 elementaryContextWindow::elementaryContextWindow(int deltaFontSize)
661 {
662 FL_NORMAL_SIZE -= deltaFontSize;
663
664 int width = 34 * FL_NORMAL_SIZE;
665 int height = 5 * WB + 10 * BH;
666
667 win = new paletteWindow(width, height,
668 CTX::instance()->nonModalWindows ? true : false,
669 "Elementary Entity Context");
670 win->box(GMSH_WINDOW_BOX);
671 {
672 tab1 = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
673 // 0: Parameter
674 {
675 group[0] = new Fl_Group(WB, WB + BH, width - 2 * WB,
676 height - 3 * WB - 2 * BH, "Parameter");
677 input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Name");
678 input[0]->value("lc");
679 input[1] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Value");
680 input[1]->value("0.1");
681 input[2] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Label");
682 input[2]->value("");
683 input[3] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Path");
684 input[3]->value("Parameters");
685 for(int i = 0; i < 4; i++) { input[i]->align(FL_ALIGN_RIGHT); }
686 {
687 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
688 height - 3 * WB - 2 * BH, BB, BH, "Add");
689 o->callback(elementary_add_parameter_cb);
690 }
691 group[0]->end();
692 }
693 // 1: Point
694 {
695 group[1] = new Fl_Group(WB, WB + BH, width - 2 * WB,
696 height - 3 * WB - 2 * BH, "Point");
697 input[4] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X");
698 input[4]->value("0");
699 input[5] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y");
700 input[5]->value("0");
701 input[6] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z");
702 input[6]->value("0");
703 input[7] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH,
704 "Prescribed mesh size at point");
705 input[7]->value("1.0");
706 for(int i = 4; i < 8; i++) {
707 input[i]->align(FL_ALIGN_RIGHT);
708 input[i]->callback(elementary_draw_point_cb);
709 }
710 {
711 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
712 height - 3 * WB - 2 * BH, BB, BH, "Add");
713 o->callback(elementary_add_point_cb);
714 }
715 group[1]->end();
716 }
717 // 2: Circle
718 {
719 group[2] = new Fl_Group(WB, WB + BH, width - 2 * WB,
720 height - 3 * WB - 2 * BH, "Circle");
721 input[8] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X");
722 input[8]->value("0");
723 input[9] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y");
724 input[9]->value("0");
725 input[10] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z");
726 input[10]->value("0");
727 input[11] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Radius");
728 input[11]->value("0.5");
729 input[12] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Angle 1");
730 input[12]->value("0");
731 input[13] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Angle 2");
732 input[13]->value("2*Pi");
733 for(int i = 8; i < 14; i++) {
734 input[i]->align(FL_ALIGN_RIGHT);
735 input[i]->callback(elementary_draw_circle_cb);
736 }
737 {
738 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
739 height - 3 * WB - 2 * BH, BB, BH, "Add");
740 o->callback(elementary_add_circle_cb);
741 }
742 group[2]->end();
743 }
744 // 3: Ellipse
745 {
746 group[3] = new Fl_Group(WB, WB + BH, width - 2 * WB,
747 height - 3 * WB - 2 * BH, "Ellipse");
748 input[14] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X");
749 input[14]->value("0");
750 input[15] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y");
751 input[15]->value("0");
752 input[16] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z");
753 input[16]->value("0");
754 input[17] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Radius X");
755 input[17]->value("0.5");
756 input[18] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Radius Y");
757 input[18]->value("0.25");
758 input[19] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Angle 1");
759 input[19]->value("0");
760 input[20] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Angle 2");
761 input[20]->value("2*Pi");
762 for(int i = 14; i < 21; i++) {
763 input[i]->align(FL_ALIGN_RIGHT);
764 input[i]->callback(elementary_draw_ellipse_cb);
765 }
766 {
767 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
768 height - 3 * WB - 2 * BH, BB, BH, "Add");
769 o->callback(elementary_add_ellipse_cb);
770 }
771 group[3]->end();
772 }
773 // 4: Disk
774 {
775 group[4] = new Fl_Group(WB, WB + BH, width - 2 * WB,
776 height - 3 * WB - 2 * BH, "Disk");
777 input[21] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X");
778 input[21]->value("0");
779 input[22] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y");
780 input[22]->value("0");
781 input[23] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z");
782 input[23]->value("0");
783 input[24] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Radius X");
784 input[24]->value("0.5");
785 input[25] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Radius Y");
786 input[25]->value("0.25");
787 for(int i = 21; i < 26; i++) {
788 input[i]->align(FL_ALIGN_RIGHT);
789 input[i]->callback(elementary_draw_disk_cb);
790 }
791 {
792 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
793 height - 3 * WB - 2 * BH, BB, BH, "Add");
794 o->callback(elementary_add_disk_cb);
795 }
796 group[4]->end();
797 }
798 // 5: Rectangle
799 {
800 group[5] = new Fl_Group(WB, WB + BH, width - 2 * WB,
801 height - 3 * WB - 2 * BH, "Rectangle");
802 input[26] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X");
803 input[26]->value("0");
804 input[27] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y");
805 input[27]->value("0");
806 input[28] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z");
807 input[28]->value("0");
808 input[29] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "DX");
809 input[29]->value("1");
810 input[30] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "DY");
811 input[30]->value("0.5");
812 input[31] =
813 new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Rounded radius");
814 input[31]->value("0");
815 for(int i = 26; i < 32; i++) {
816 input[i]->align(FL_ALIGN_RIGHT);
817 input[i]->callback(elementary_draw_rectangle_cb);
818 }
819 {
820 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
821 height - 3 * WB - 2 * BH, BB, BH, "Add");
822 o->callback(elementary_add_rectangle_cb);
823 }
824 group[5]->end();
825 }
826 tab1->end();
827 }
828 {
829 tab2 = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
830 // 6: Sphere
831 {
832 group[6] = new Fl_Group(WB, WB + BH, width - 2 * WB,
833 height - 3 * WB - 2 * BH, "Sphere");
834 input[32] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X");
835 input[32]->value("0");
836 input[33] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y");
837 input[33]->value("0");
838 input[34] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z");
839 input[34]->value("0");
840 input[35] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Radius");
841 input[35]->value("0.5");
842 input[36] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Angle 1");
843 input[36]->value("-Pi/2");
844 input[37] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Angle 2");
845 input[37]->value("Pi/2");
846 input[38] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Angle 3");
847 input[38]->value("2*Pi");
848 for(int i = 32; i < 39; i++) {
849 input[i]->align(FL_ALIGN_RIGHT);
850 input[i]->callback(elementary_draw_sphere_cb);
851 }
852 {
853 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
854 height - 3 * WB - 2 * BH, BB, BH, "Add");
855 o->callback(elementary_add_sphere_cb);
856 }
857 group[6]->end();
858 }
859 // 7: Cylinder
860 {
861 group[7] = new Fl_Group(WB, WB + BH, width - 2 * WB,
862 height - 3 * WB - 2 * BH, "Cylinder");
863 input[39] =
864 new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center base X");
865 input[39]->value("0");
866 input[40] =
867 new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center base Y");
868 input[40]->value("0");
869 input[41] =
870 new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center base Z");
871 input[41]->value("0");
872 input[42] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Axis DX");
873 input[42]->value("1");
874 input[43] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Axis DY");
875 input[43]->value("0");
876 input[44] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Axis DZ");
877 input[44]->value("0");
878 input[45] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Radius");
879 input[45]->value("0.5");
880 input[46] = new Fl_Input(2 * WB, 2 * WB + 8 * BH, IW, BH, "Angle");
881 input[46]->value("2*Pi");
882 for(int i = 39; i < 47; i++) {
883 input[i]->align(FL_ALIGN_RIGHT);
884 input[i]->callback(elementary_draw_cylinder_cb);
885 }
886 {
887 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
888 height - 3 * WB - 2 * BH, BB, BH, "Add");
889 o->callback(elementary_add_cylinder_cb);
890 }
891 group[7]->end();
892 }
893 // 8: Box
894 {
895 group[8] = new Fl_Group(WB, WB + BH, width - 2 * WB,
896 height - 3 * WB - 2 * BH, "Box");
897 input[47] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X");
898 input[47]->value("0");
899 input[48] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y");
900 input[48]->value("0");
901 input[49] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z");
902 input[49]->value("0");
903 input[50] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "DX");
904 input[50]->value("1");
905 input[51] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "DY");
906 input[51]->value("1");
907 input[52] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "DZ");
908 input[52]->value("1");
909 for(int i = 47; i < 53; i++) {
910 input[i]->align(FL_ALIGN_RIGHT);
911 input[i]->callback(elementary_draw_box_cb);
912 }
913 {
914 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
915 height - 3 * WB - 2 * BH, BB, BH, "Add");
916 o->callback(elementary_add_box_cb);
917 }
918 group[8]->end();
919 }
920 // 9: Torus
921 {
922 group[9] = new Fl_Group(WB, WB + BH, width - 2 * WB,
923 height - 3 * WB - 2 * BH, "Torus");
924 input[53] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X");
925 input[53]->value("0");
926 input[54] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y");
927 input[54]->value("0");
928 input[55] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z");
929 input[55]->value("0");
930 input[56] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Radius 1");
931 input[56]->value("0.5");
932 input[57] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Radius 2");
933 input[57]->value("0.2");
934 input[58] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Angle");
935 input[58]->value("2*Pi");
936 for(int i = 53; i < 59; i++) {
937 input[i]->align(FL_ALIGN_RIGHT);
938 input[i]->callback(elementary_draw_torus_cb);
939 }
940 {
941 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
942 height - 3 * WB - 2 * BH, BB, BH, "Add");
943 o->callback(elementary_add_torus_cb);
944 }
945 group[9]->end();
946 }
947 // 10: Cone
948 {
949 group[10] = new Fl_Group(WB, WB + BH, width - 2 * WB,
950 height - 3 * WB - 2 * BH, "Cone");
951 input[59] =
952 new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center base X");
953 input[59]->value("0");
954 input[60] =
955 new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center base Y");
956 input[60]->value("0");
957 input[61] =
958 new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center base Z");
959 input[61]->value("0");
960 input[62] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Axis DX");
961 input[62]->value("1");
962 input[63] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Axis DY");
963 input[63]->value("0");
964 input[64] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Axis DZ");
965 input[64]->value("0");
966 input[65] = new Fl_Input(2 * WB + (width - 2 * WB) / 2, 2 * WB + 4 * BH,
967 IW, BH, "Radius 1");
968 input[65]->value("0.5");
969 input[66] = new Fl_Input(2 * WB + (width - 2 * WB) / 2, 2 * WB + 5 * BH,
970 IW, BH, "Radius 2");
971 input[66]->value("0.1");
972 input[67] = new Fl_Input(2 * WB + (width - 2 * WB) / 2, 2 * WB + 6 * BH,
973 IW, BH, "Angle");
974 input[67]->value("2*Pi");
975 for(int i = 59; i < 68; i++) {
976 input[i]->align(FL_ALIGN_RIGHT);
977 input[i]->callback(elementary_draw_cone_cb);
978 }
979 {
980 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
981 height - 3 * WB - 2 * BH, BB, BH, "Add");
982 o->callback(elementary_add_cone_cb);
983 }
984 group[10]->end();
985 }
986 // 11: Wedge
987 {
988 group[11] = new Fl_Group(WB, WB + BH, width - 2 * WB,
989 height - 3 * WB - 2 * BH, "Wedge");
990 input[68] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X");
991 input[68]->value("0");
992 input[69] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y");
993 input[69]->value("0");
994 input[70] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z");
995 input[70]->value("0");
996 input[71] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "DX");
997 input[71]->value("0.5");
998 input[72] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "DY");
999 input[72]->value("0.5");
1000 input[73] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "DZ");
1001 input[73]->value("0.5");
1002 input[74] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Top DX");
1003 input[74]->value("0");
1004 for(int i = 68; i < 75; i++) {
1005 input[i]->align(FL_ALIGN_RIGHT);
1006 input[i]->callback(elementary_draw_wedge_cb);
1007 }
1008 {
1009 Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
1010 height - 3 * WB - 2 * BH, BB, BH, "Add");
1011 o->callback(elementary_add_wedge_cb);
1012 }
1013 group[11]->end();
1014 }
1015 tab2->end();
1016 }
1017
1018 {
1019 Fl_Button *o = new Fl_Button(width - 4 * WB, WB, 3 * WB, 3 * WB, "...");
1020 o->callback(elementary_switch_tabs_cb);
1021 }
1022 {
1023 value[0] = new Fl_Value_Input(WB, height - WB - BH, IW / 3, BH, "X");
1024 value[1] =
1025 new Fl_Value_Input(WB + IW / 2, height - WB - BH, IW / 3, BH, "Y");
1026 value[2] =
1027 new Fl_Value_Input(WB + IW, height - WB - BH, IW / 3, BH, "Z snap");
1028 for(int i = 0; i < 3; i++) {
1029 value[i]->align(FL_ALIGN_RIGHT);
1030 value[i]->callback(elementary_snap_cb);
1031 }
1032 butt[0] =
1033 new Fl_Check_Button(width - 6 * BH, height - WB - BH, 1.2 * BH, BH, "X");
1034 butt[0]->tooltip("Toggle (x) or exclusive unselect (Shift+x)");
1035 butt[1] = new Fl_Check_Button(width - 6 * BH + 1.2 * BH, height - WB - BH,
1036 1.2 * BH, BH, "Y");
1037 butt[1]->tooltip("Toggle (y) or exclusive unselect (Shift+y)");
1038 butt[2] = new Fl_Check_Button(width - 6 * BH + 2.4 * BH, height - WB - BH,
1039 (6 - 2 * 1.2) * BH - WB, BH, "Z freeze");
1040 butt[2]->tooltip("Toggle (z) or exclusive unselect (Shift+z)");
1041 }
1042
1043 tab1->show();
1044 tab2->hide();
1045
1046 win->position(CTX::instance()->ctxPosition[0],
1047 CTX::instance()->ctxPosition[1]);
1048 win->end();
1049
1050 FL_NORMAL_SIZE += deltaFontSize;
1051 }
1052
frozenPointCoord(int coord)1053 bool elementaryContextWindow::frozenPointCoord(int coord)
1054 {
1055 if(coord < 0 || coord > 2) return false;
1056 return butt[coord]->value() ? true : false;
1057 }
1058
updatePoint(double pt[3],int which)1059 void elementaryContextWindow::updatePoint(double pt[3], int which)
1060 {
1061 for(int i = 0; i < 3; i++) {
1062 if(!frozenPointCoord(i)) {
1063 char str[32];
1064 sprintf(str, "%g", pt[i]);
1065 if(which == 1) {
1066 int start[11] = {4, 8, 14, 21, 26, 32, 39, 47, 53, 59, 68};
1067 for(int k = 0; k < 11; k++) {
1068 input[start[k] + i]->value(str);
1069 if(input[start[k] + i]->parent()->active()) {
1070 input[start[k] + i]->do_callback(nullptr, (void *)"no_redraw");
1071 }
1072 }
1073 }
1074 }
1075 }
1076 }
1077
show(int pane)1078 void elementaryContextWindow::show(int pane)
1079 {
1080 FlGui::instance()->lastContextWindow = 0;
1081
1082 if(pane < 0 || pane > 11) return;
1083
1084 for(int i = 0; i < 12; i++) {
1085 group[i]->hide();
1086 group[i]->deactivate();
1087 }
1088
1089 if(pane < 6) {
1090 tab1->show();
1091 tab2->hide();
1092 }
1093 else {
1094 tab1->hide();
1095 tab2->show();
1096 }
1097
1098 group[pane]->show();
1099 group[pane]->activate();
1100 win->show();
1101 }
1102
physical_add_cb(Fl_Widget * w,void * data)1103 static void physical_add_cb(Fl_Widget *w, void *data)
1104 {
1105 std::string what = data ? (const char *)data : "";
1106
1107 physicalContextWindow *pc = FlGui::instance()->physicalContext;
1108 std::string name = pc->input[0]->value();
1109 int tag = pc->value[0]->value();
1110 std::string existingName = "";
1111 int existingTag = 0;
1112 if(what != "Tag") {
1113 auto it = pc->physicalNames.find(name);
1114 if(it != pc->physicalNames.end()) {
1115 existingName = name;
1116 existingTag = it->second;
1117 }
1118 }
1119 if(what != "Name") {
1120 auto it = pc->physicalTags.find(tag);
1121 if(it != pc->physicalTags.end()) {
1122 existingTag = tag;
1123 existingName = it->second;
1124 }
1125 }
1126
1127 if(existingName.size() || existingTag) {
1128 // change color to warn that the group exists
1129 Fl_Color c = (!CTX::instance()->guiColorScheme ? FL_DARK_BLUE : FL_BLUE);
1130 pc->input[0]->textcolor(c);
1131 pc->value[0]->textcolor(c);
1132 if(what != "Name" && !strlen(pc->input[0]->value()))
1133 pc->input[0]->value(existingName.c_str());
1134 if(what != "Tag") pc->value[0]->value(existingTag);
1135 pc->append = true;
1136 }
1137 else {
1138 pc->input[0]->textcolor(FL_FOREGROUND_COLOR);
1139 pc->value[0]->textcolor(FL_FOREGROUND_COLOR);
1140 if(what != "Tag") pc->value[0]->value(NEWPHYSICAL());
1141 pc->append = false;
1142 }
1143
1144 if(pc->butt[0]->active()) {
1145 if(pc->butt[0]->value())
1146 pc->value[0]->deactivate();
1147 else
1148 pc->value[0]->activate();
1149 }
1150
1151 pc->input[0]->redraw();
1152 pc->value[0]->redraw();
1153
1154 pc->selectedName = pc->input[0]->value();
1155 pc->selectedTag = pc->value[0]->value();
1156 }
1157
physical_remove_cb(Fl_Widget * w,void * data)1158 static void physical_remove_cb(Fl_Widget *w, void *data)
1159 {
1160 physicalContextWindow *pc = FlGui::instance()->physicalContext;
1161 int tag = 0;
1162 std::string name = "";
1163 if(pc->choice[0]->text()) {
1164 std::vector<std::string> tmp = SplitString(pc->choice[0]->text(), ':');
1165 tag = (tmp.size() > 0) ? atoi(tmp[0].c_str()) : 0;
1166 name = (tmp.size() > 1) ? tmp[1] : "";
1167 }
1168
1169 pc->selectedName = name;
1170 pc->selectedTag = tag;
1171 }
1172
physicalContextWindow(int deltaFontSize)1173 physicalContextWindow::physicalContextWindow(int deltaFontSize)
1174 : selectedTag(0), type(""), mode("Add"), selectedName(""), append(false)
1175 {
1176 FL_NORMAL_SIZE -= deltaFontSize;
1177
1178 int width = 30 * FL_NORMAL_SIZE;
1179 int height = 5 * WB + 4 * BH;
1180
1181 win = new paletteWindow(width, height,
1182 CTX::instance()->nonModalWindows ? true : false,
1183 "Physical Group Context");
1184 win->box(GMSH_WINDOW_BOX);
1185
1186 {
1187 tab = new Fl_Tabs(WB, WB, width - 2 * WB, 4 * BH + 3 * WB);
1188 // 0: Add
1189 {
1190 group[0] =
1191 new Fl_Group(WB, WB + BH, width - 2 * WB, 3 * BH + 3 * WB, "Add");
1192
1193 box[0] = new Fl_Box(2 * WB, 2 * WB + 1 * BH, width, BH);
1194 box[0]->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
1195
1196 input[0] = new Fl_Input_Choice(2 * WB, 2 * WB + 2 * BH,
1197 (int)(0.6 * width), BH, "Name");
1198 input[0]->value("");
1199 input[0]->align(FL_ALIGN_RIGHT);
1200 input[0]->callback(physical_add_cb, (void *)"Name");
1201 input[0]->when(FL_WHEN_CHANGED);
1202
1203 value[0] = new Fl_Value_Input(2 * WB, 2 * WB + 3 * BH, (int)(0.6 * width),
1204 BH, "Tag");
1205 value[0]->value(0);
1206 value[0]->deactivate();
1207 value[0]->align(FL_ALIGN_RIGHT);
1208 value[0]->callback(physical_add_cb, (void *)"Tag");
1209 value[0]->when(FL_WHEN_CHANGED);
1210
1211 butt[0] = new Fl_Check_Button(width - width / 4, 2 * WB + 3 * BH,
1212 width / 4 - 2 * WB, BH, "Automatic");
1213 butt[0]->value(1);
1214 butt[0]->callback(physical_add_cb);
1215
1216 group[0]->end();
1217 }
1218 // 1: Remove
1219 {
1220 group[1] =
1221 new Fl_Group(WB, WB + BH, width - 2 * WB, 3 * BH + 3 * WB, "Remove");
1222
1223 box[1] = new Fl_Box(2 * WB, 2 * WB + 1 * BH, width, BH);
1224 box[1]->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
1225
1226 choice[0] =
1227 new Fl_Choice(2 * WB, 2 * WB + 2 * BH, (int)(0.6 * width), BH);
1228 choice[0]->align(FL_ALIGN_RIGHT);
1229 choice[0]->callback(physical_remove_cb);
1230
1231 group[1]->end();
1232 }
1233 tab->end();
1234 }
1235
1236 win->position(CTX::instance()->ctxPosition[0],
1237 CTX::instance()->ctxPosition[1]);
1238 win->end();
1239
1240 FL_NORMAL_SIZE += deltaFontSize;
1241 }
1242
show(const std::string & what,bool remove)1243 void physicalContextWindow::show(const std::string &what, bool remove)
1244 {
1245 FlGui::instance()->lastContextWindow = 3;
1246
1247 // update window title and labels
1248 type = what;
1249 int dim;
1250 if(type == "Volume")
1251 dim = 3;
1252 else if(type == "Surface")
1253 dim = 2;
1254 else if(type == "Curve")
1255 dim = 1;
1256 else if(type == "Point")
1257 dim = 0;
1258 else {
1259 Msg::Error("Unknown physical context '%s'", type.c_str());
1260 return;
1261 }
1262 win->copy_label(std::string("Physical " + type + " Context").c_str());
1263 std::string s(" and select " + type + "(s) to ");
1264 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
1265 box[0]->copy_label(
1266 std::string("Create or choose group," + s + "add").c_str());
1267 box[1]->copy_label(std::string("Choose group" + s + "remove").c_str());
1268
1269 // get all physical group tags and names (this is relatively expensive - so we
1270 // shouldn't do it in the callbacks)
1271 std::map<int, std::vector<GEntity *> > groups;
1272 GModel::current()->getPhysicalGroups(dim, groups);
1273 physicalTags.clear();
1274 physicalNames.clear();
1275 for(auto &p : groups) {
1276 std::string name = GModel::current()->getPhysicalName(dim, p.first);
1277 physicalTags[p.first] = name;
1278 if(name.size()) physicalNames[name] = p.first;
1279 }
1280
1281 // create menus with existing physicals
1282 std::vector<Fl_Menu_Item> menuAdd, menuRemove;
1283 static std::vector<char *> toFree;
1284 for(std::size_t i = 0; i < toFree.size(); i++) free(toFree[i]);
1285 toFree.clear();
1286 {
1287 for(auto &p : physicalNames) {
1288 char *str = strdup(p.first.c_str());
1289 Fl_Menu_Item item = {str, 0, nullptr, nullptr, 0};
1290 toFree.push_back(str);
1291 menuAdd.push_back(item);
1292 }
1293 Fl_Menu_Item item = {nullptr};
1294 menuAdd.push_back(item);
1295 input[0]->menubutton()->copy(&menuAdd[0]);
1296 }
1297 {
1298 for(auto &p : physicalTags) {
1299 std::string label = std::to_string(p.first);
1300 if(p.second.size()) label += ": " + p.second;
1301 char *str = strdup(label.c_str());
1302 Fl_Menu_Item item = {str, 0, nullptr, nullptr, 0};
1303 toFree.push_back(str);
1304 menuRemove.push_back(item);
1305 }
1306 Fl_Menu_Item item = {nullptr};
1307 menuRemove.push_back(item);
1308 choice[0]->copy(&menuRemove[0]);
1309 }
1310
1311 // activate the relevant tabs and widgets
1312 for(int i = 0; i < 2; i++) {
1313 group[i]->hide();
1314 group[i]->deactivate();
1315 }
1316 if(remove) {
1317 mode = "Remove";
1318 group[1]->show();
1319 group[1]->activate();
1320 physical_remove_cb(nullptr, nullptr);
1321 }
1322 else {
1323 mode = "Add";
1324 group[0]->show();
1325 group[0]->activate();
1326 if(butt[0]->value())
1327 value[0]->deactivate();
1328 else
1329 value[0]->activate();
1330 physical_add_cb(nullptr, (void *)"Name");
1331 }
1332
1333 if(!win->shown()) win->show();
1334 }
1335
1336 static Fl_Menu_Item menu_selection_mode[] = {
1337 {"All entities", 0, nullptr, nullptr}, {"Points", 0, nullptr, nullptr},
1338 {"Curves", 0, nullptr, nullptr}, {"Surfaces", 0, nullptr, nullptr},
1339 {"Volumes", 0, nullptr, nullptr}, {nullptr}};
1340
selection_mode_cb(Fl_Widget * w,void * data)1341 static void selection_mode_cb(Fl_Widget *w, void *data)
1342 {
1343 Fl_Choice *c = (Fl_Choice *)w;
1344 int mode = ENT_ALL;
1345 switch(c->value()) {
1346 case 1:
1347 mode = ENT_POINT;
1348 opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
1349 break;
1350 case 2:
1351 mode = ENT_CURVE;
1352 opt_geometry_curves(0, GMSH_SET | GMSH_GUI, 1);
1353 break;
1354 case 3:
1355 mode = ENT_SURFACE;
1356 opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
1357 break;
1358 case 4:
1359 mode = ENT_VOLUME;
1360 opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
1361 break;
1362 }
1363 for(std::size_t i = 0; i < FlGui::instance()->graph.size(); i++)
1364 for(std::size_t j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++)
1365 FlGui::instance()->graph[i]->gl[j]->changeSelection = mode;
1366 drawContext::global()->draw();
1367 }
1368
transformContextWindow(int deltaFontSize)1369 transformContextWindow::transformContextWindow(int deltaFontSize)
1370 {
1371 FL_NORMAL_SIZE -= deltaFontSize;
1372
1373 int width = 34 * FL_NORMAL_SIZE;
1374 int height = 5 * WB + 10 * BH;
1375
1376 win = new paletteWindow(width, height,
1377 CTX::instance()->nonModalWindows ? true : false,
1378 "Elementary Operation Context");
1379 win->box(GMSH_WINDOW_BOX);
1380 {
1381 Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
1382 // 0: Translate
1383 {
1384 group[0] = new Fl_Group(WB, WB + BH, width - 2 * WB,
1385 height - 3 * WB - 2 * BH, "Translate");
1386 input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "DX");
1387 input[0]->value("0");
1388 input[1] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "DY");
1389 input[1]->value("0");
1390 input[2] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "DZ");
1391 input[2]->value("1");
1392 for(int i = 0; i < 3; i++) { input[i]->align(FL_ALIGN_RIGHT); }
1393 butt[0] = new Fl_Check_Button(2 * WB, 2 * WB + 4 * BH, width - 4 * WB, BH,
1394 "Apply translation on copy");
1395 butt[0]->value(0);
1396 butt[7] = new Fl_Check_Button(2 * WB, 2 * WB + 5 * BH, width - 4 * WB, BH,
1397 "Extrude mesh");
1398 butt[7]->value(0);
1399 input[21] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Mesh layers");
1400 input[21]->value("5");
1401 input[21]->align(FL_ALIGN_RIGHT);
1402 butt[8] = new Fl_Check_Button(width / 2 + 2 * WB, 2 * WB + 6 * BH,
1403 width / 2 - 4 * WB, BH, "Recombine");
1404 butt[8]->value(1);
1405 group[0]->end();
1406 }
1407 // 1: Rotate
1408 {
1409 group[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1410 "Rotate");
1411 input[3] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Axis point X");
1412 input[3]->value("0");
1413 input[4] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Axis point Y");
1414 input[4]->value("0");
1415 input[5] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Axis point Z");
1416 input[5]->value("0");
1417 input[6] =
1418 new Fl_Input(width / 2 + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Axis DX");
1419 input[6]->value("0");
1420 input[7] =
1421 new Fl_Input(width / 2 + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Axis DY");
1422 input[7]->value("1");
1423 input[8] =
1424 new Fl_Input(width / 2 + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Axis DZ");
1425 input[8]->value("0");
1426 input[9] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Angle");
1427 input[9]->value("Pi/4");
1428 for(int i = 3; i < 10; i++) { input[i]->align(FL_ALIGN_RIGHT); }
1429 butt[1] = new Fl_Check_Button(2 * WB, 2 * WB + 5 * BH, width - 4 * WB, BH,
1430 "Apply rotation on copy");
1431 butt[1]->value(0);
1432 butt[9] = new Fl_Check_Button(2 * WB, 2 * WB + 6 * BH, width - 4 * WB, BH,
1433 "Extrude mesh");
1434 butt[9]->value(0);
1435 input[22] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Mesh layers");
1436 input[22]->value("5");
1437 input[22]->align(FL_ALIGN_RIGHT);
1438 butt[10] = new Fl_Check_Button(width / 2 + 2 * WB, 2 * WB + 7 * BH,
1439 width / 2 - 4 * WB, BH, "Recombine");
1440 butt[10]->value(1);
1441 group[1]->end();
1442 }
1443 // 2: Scale
1444 {
1445 group[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1446 "Scale");
1447 input[10] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X");
1448 input[10]->value("0");
1449 input[11] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y");
1450 input[11]->value("0");
1451 input[12] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z");
1452 input[12]->value("0");
1453 input[13] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Scale X");
1454 input[13]->value("0.5");
1455 input[14] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Scale Y");
1456 input[14]->value("0.5");
1457 input[15] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Scale Z");
1458 input[15]->value("0.5");
1459 for(int i = 10; i < 16; i++) { input[i]->align(FL_ALIGN_RIGHT); }
1460 butt[2] = new Fl_Check_Button(2 * WB, 2 * WB + 7 * BH, width - 4 * WB, BH,
1461 "Apply scaling on copy");
1462 butt[2]->value(0);
1463 group[2]->end();
1464 }
1465 // 3: Symmetry
1466 {
1467 group[3] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1468 "Symmetry");
1469 input[16] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Plane A");
1470 input[16]->value("1");
1471 input[17] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Plane B");
1472 input[17]->value("0");
1473 input[18] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Plane C");
1474 input[18]->value("0");
1475 input[19] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Plane D");
1476 input[19]->value("1");
1477 for(int i = 16; i < 20; i++) { input[i]->align(FL_ALIGN_RIGHT); }
1478 butt[3] = new Fl_Check_Button(2 * WB, 2 * WB + 5 * BH, width - 4 * WB, BH,
1479 "Apply symmetry on copy");
1480 butt[3]->value(0);
1481 group[3]->end();
1482 }
1483 // 4: Boolean
1484 {
1485 group[4] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1486 "Boolean");
1487 butt[4] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, width - 4 * WB, BH,
1488 "Delete object");
1489 butt[4]->value(1);
1490 butt[5] = new Fl_Check_Button(2 * WB, 2 * WB + 2 * BH, width - 4 * WB, BH,
1491 "Delete tool");
1492 butt[5]->value(1);
1493 group[4]->end();
1494 }
1495 // 5: Fillet
1496 {
1497 group[5] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1498 "Fillet");
1499 input[20] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Radius");
1500 input[20]->value("0.1");
1501 input[20]->align(FL_ALIGN_RIGHT);
1502 group[5]->end();
1503 }
1504 // 6: Delete
1505 {
1506 group[6] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1507 "Delete");
1508 butt[6] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, width - 4 * WB, BH,
1509 "Recursive");
1510 butt[6]->value(1);
1511 group[6]->end();
1512 }
1513 o->end();
1514 }
1515
1516 choice = new Fl_Choice(WB, height - WB - BH, IW, BH, "Selection mode");
1517 choice->menu(menu_selection_mode);
1518 choice->align(FL_ALIGN_RIGHT);
1519 choice->callback(selection_mode_cb);
1520
1521 win->position(CTX::instance()->ctxPosition[0],
1522 CTX::instance()->ctxPosition[1]);
1523 win->end();
1524
1525 FL_NORMAL_SIZE += deltaFontSize;
1526 }
1527
show(int pane,bool extrude,bool selection)1528 void transformContextWindow::show(int pane, bool extrude, bool selection)
1529 {
1530 FlGui::instance()->lastContextWindow = 1;
1531
1532 for(int i = 0; i < 7; i++) {
1533 group[i]->hide();
1534 group[i]->deactivate();
1535 }
1536 for(int i = 0; i < 4; i++) {
1537 if(extrude)
1538 butt[i]->deactivate();
1539 else
1540 butt[i]->activate();
1541 }
1542 for(int i = 7; i < 11; i++) {
1543 if(!extrude)
1544 butt[i]->deactivate();
1545 else
1546 butt[i]->activate();
1547 }
1548 for(int i = 21; i < 23; i++) {
1549 if(!extrude)
1550 input[i]->deactivate();
1551 else
1552 input[i]->activate();
1553 }
1554 if(selection)
1555 choice->activate();
1556 else
1557 choice->deactivate();
1558 if(pane < 0 || pane > 6) { group[0]->show(); }
1559 else {
1560 group[pane]->show();
1561 group[pane]->activate();
1562 }
1563 win->show();
1564 }
1565
meshContextWindow(int deltaFontSize)1566 meshContextWindow::meshContextWindow(int deltaFontSize)
1567 {
1568 FL_NORMAL_SIZE -= deltaFontSize;
1569
1570 static Fl_Menu menu_transfinite_dir[] = {{"Left", 0, nullptr, nullptr},
1571 {"Right", 0, nullptr, nullptr},
1572 {"Alternated", 0, nullptr, nullptr},
1573 {nullptr}};
1574
1575 int width = 29 * FL_NORMAL_SIZE;
1576 int height = 4 * WB + 4 * BH;
1577
1578 win = new paletteWindow(width, height, CTX::instance()->nonModalWindows,
1579 "Mesh Context");
1580 win->box(GMSH_WINDOW_BOX);
1581 {
1582 Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
1583 // 0: Element size at points
1584 {
1585 group[0] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1586 "Element size");
1587 input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Value");
1588 input[0]->value("0.1");
1589 input[0]->align(FL_ALIGN_RIGHT);
1590 group[0]->end();
1591 }
1592 // 1: Transfinite line
1593 {
1594 group[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1595 "Transfinite curve");
1596 input[1] =
1597 new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Number of points");
1598 input[1]->value("10");
1599 input[2] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Parameter");
1600 input[2]->value("1");
1601 for(int i = 1; i < 3; i++) { input[i]->align(FL_ALIGN_RIGHT); }
1602 static Fl_Menu_Item menu_trsf_mesh[] = {
1603 {"Progression", 0, nullptr, nullptr},
1604 {"Bump", 0, nullptr, nullptr},
1605 {"Beta", 0, nullptr, nullptr},
1606 {nullptr}};
1607 choice[0] = new Fl_Choice(2 * WB, 2 * WB + 2 * BH, IW, BH, "Type");
1608 choice[0]->menu(menu_trsf_mesh);
1609 choice[0]->align(FL_ALIGN_RIGHT);
1610 group[1]->end();
1611 }
1612
1613 // 2: Transfinite surface
1614 {
1615 group[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH,
1616 "Transfinite Surface");
1617
1618 choice[1] = new Fl_Choice(2 * WB, 2 * WB + 1 * BH, IW, BH,
1619 "Transfinite Arrangement");
1620 choice[1]->menu(menu_transfinite_dir);
1621 choice[1]->align(FL_ALIGN_RIGHT);
1622
1623 group[2]->end();
1624 }
1625 o->end();
1626 }
1627
1628 win->position(CTX::instance()->ctxPosition[0],
1629 CTX::instance()->ctxPosition[1]);
1630 win->end();
1631
1632 FL_NORMAL_SIZE += deltaFontSize;
1633 }
1634
show(int pane)1635 void meshContextWindow::show(int pane)
1636 {
1637 FlGui::instance()->lastContextWindow = 2;
1638
1639 for(int i = 0; i < 3; i++) {
1640 group[i]->hide();
1641 group[i]->deactivate();
1642 }
1643 group[pane]->show();
1644 group[pane]->activate();
1645 win->show();
1646 }
1647