Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-09-22 |
2 | // Created by: Didier PIFFAULT | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
4006ca98 | 17 | #include <MeshTest.hxx> |
18 | ||
19 | #include <stdio.h> | |
7fd59977 | 20 | |
42cf5bc1 | 21 | #include <Bnd_Box.hxx> |
7fd59977 | 22 | #include <BRep_Builder.hxx> |
42cf5bc1 | 23 | #include <BRepAdaptor_Surface.hxx> |
24 | #include <BRepBndLib.hxx> | |
25 | #include <BRepBuilderAPI_MakeFace.hxx> | |
26 | #include <BRepBuilderAPI_MakePolygon.hxx> | |
27 | #include <BRepBuilderAPI_MakeVertex.hxx> | |
28 | #include <BRepLib.hxx> | |
7fd59977 | 29 | #include <BRepMesh_IncrementalMesh.hxx> |
42cf5bc1 | 30 | #include <BRepTest.hxx> |
31 | #include <BRepTools.hxx> | |
32 | #include <CSLib.hxx> | |
42cf5bc1 | 33 | #include <DBRep.hxx> |
42cf5bc1 | 34 | #include <Draw_Appli.hxx> |
ce97cd97 | 35 | #include <Draw_ProgressIndicator.hxx> |
7fd59977 | 36 | #include <Draw_Segment2D.hxx> |
42cf5bc1 | 37 | #include <DrawTrSurf.hxx> |
42cf5bc1 | 38 | #include <GeometryTest.hxx> |
4006ca98 | 39 | #include <IMeshData_Status.hxx> |
d99f0355 | 40 | #include <Message.hxx> |
ce97cd97 | 41 | #include <Message_ProgressRange.hxx> |
84d0342c | 42 | #include <OSD_OpenFile.hxx> |
7fd59977 | 43 | #include <Poly_Connect.hxx> |
7fd59977 | 44 | #include <TopExp_Explorer.hxx> |
d51c7072 | 45 | #include <TopTools_MapIteratorOfMapOfShape.hxx> |
5bae0beb | 46 | #include <BRep_CurveRepresentation.hxx> |
47 | #include <BRep_TEdge.hxx> | |
48 | #include <TopExp.hxx> | |
d51c7072 | 49 | |
f2006a6f | 50 | #include <BRepMesh_Context.hxx> |
51 | #include <BRepMesh_FaceDiscret.hxx> | |
52 | #include <BRepMesh_MeshAlgoFactory.hxx> | |
53 | #include <BRepMesh_DelabellaMeshAlgoFactory.hxx> | |
54 | ||
42cf5bc1 | 55 | //epa Memory leaks test |
56 | //OAN: for triepoints | |
57c28b61 | 57 | #ifdef _WIN32 |
7fd59977 | 58 | Standard_IMPORT Draw_Viewer dout; |
59 | #endif | |
60 | ||
61 | #define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) ) | |
62 | #define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) ) | |
63 | ||
7fd59977 | 64 | #define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333 |
65 | #define TWOTHIRD 0.666666666666666666666666666666666666666666666666666666666666 | |
66 | ||
0797d9d3 | 67 | #ifdef OCCT_DEBUG_MESH_CHRONO |
7fd59977 | 68 | #include <OSD_Chronometer.hxx> |
69 | Standard_Integer D0Control, D0Internal, D0Unif, D0Edges, NbControls; | |
70 | OSD_Chronometer chTotal, chInternal, chControl, chUnif, chAddPoint; | |
71 | OSD_Chronometer chEdges, chMaillEdges, chEtuInter, chLastControl, chStock; | |
72 | OSD_Chronometer chAdd11, chAdd12, chAdd2, chUpdate, chPointValid; | |
73 | OSD_Chronometer chIsos, chPointsOnIsos; | |
74 | #endif | |
75 | ||
7fd59977 | 76 | //======================================================================= |
77 | //function : incrementalmesh | |
78 | //purpose : | |
79 | //======================================================================= | |
d51c7072 | 80 | static Standard_Integer incrementalmesh(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv) |
7fd59977 | 81 | { |
49cfd13d | 82 | if (nbarg < 3) |
83 | { | |
84 | di << "\ | |
85 | Builds triangular mesh for the shape\n\ | |
86 | usage: incmesh Shape LinearDeflection [options]\n\ | |
87 | options:\n\ | |
46478ffe | 88 | -a val angular deflection for edges in deg\n\ |
74da0216 | 89 | (default ~28.64 deg = 0.5 rad)\n\n\ |
46478ffe | 90 | -ai val angular deflection inside of faces in deg\n\ |
91 | (default ~57.29 deg = 1 rad)\n\n\ | |
92 | -di val Linear deflection used to tessellate the face interior.\n\ | |
74da0216 | 93 | -min minimum size parameter limiting size of triangle's\n\ |
94 | edges to prevent sinking into amplification in case\n\ | |
95 | of distorted curves and surfaces\n\n\ | |
49cfd13d | 96 | -relative notifies that relative deflection is used\n\ |
74da0216 | 97 | (switched off by default)\n\n\ |
a319f03f | 98 | -int_vert_off disables insertion of internal vertices into mesh\n\ |
99 | (enabled by default)\n\ | |
f43eff9f | 100 | -surf_def_off disables control of deflection of mesh from real\n\ |
101 | surface (enabled by default)\n\ | |
e71669c6 | 102 | -parallel enables parallel execution (switched off by default)\n\ |
0da2ecac | 103 | -adjust_min enables local adjustment of min size depending on edge size (switched off by default)\n\ |
128654b6 | 104 | -force_face_def disables usage of shape tolerances for computing face deflection (switched off by default)\n\ |
105 | -decrease enforces the meshing of the shape even if current mesh satisfies the new criteria\ | |
f2006a6f | 106 | (switched off by default).\n\ |
107 | -algo {watson|delabella} changes core triangulation algorithm to one with specified id (watson is used by default)\n"; | |
416d4426 | 108 | return 0; |
109 | } | |
7fd59977 | 110 | |
416d4426 | 111 | TopoDS_Shape aShape = DBRep::Get(argv[1]); |
49cfd13d | 112 | if (aShape.IsNull()) |
113 | { | |
114 | di << " Null shapes are not allowed here\n"; | |
416d4426 | 115 | return 0; |
116 | } | |
416d4426 | 117 | |
7bd071ed | 118 | IMeshTools_Parameters aMeshParams; |
46478ffe | 119 | aMeshParams.Deflection = aMeshParams.DeflectionInterior = |
120 | Max(Draw::Atof(argv[2]), Precision::Confusion()); | |
49cfd13d | 121 | |
f2006a6f | 122 | Handle (IMeshTools_Context) aContext = new BRepMesh_Context; |
49cfd13d | 123 | if (nbarg > 3) |
124 | { | |
125 | Standard_Integer i = 3; | |
126 | while (i < nbarg) | |
127 | { | |
128 | TCollection_AsciiString aOpt(argv[i++]); | |
129 | aOpt.LowerCase(); | |
130 | ||
131 | if (aOpt == "") | |
132 | continue; | |
133 | else if (aOpt == "-relative") | |
7bd071ed | 134 | aMeshParams.Relative = Standard_True; |
49cfd13d | 135 | else if (aOpt == "-parallel") |
7bd071ed | 136 | aMeshParams.InParallel = Standard_True; |
a319f03f | 137 | else if (aOpt == "-int_vert_off") |
7bd071ed | 138 | aMeshParams.InternalVerticesMode = Standard_False; |
f43eff9f | 139 | else if (aOpt == "-surf_def_off") |
7bd071ed | 140 | aMeshParams.ControlSurfaceDeflection = Standard_False; |
3c1b7084 | 141 | else if (aOpt == "-adjust_min") |
142 | aMeshParams.AdjustMinSize = Standard_True; | |
0da2ecac | 143 | else if (aOpt == "-force_face_def") |
144 | aMeshParams.ForceFaceDeflection = Standard_True; | |
128654b6 | 145 | else if (aOpt == "-decrease") |
146 | aMeshParams.AllowQualityDecrease = Standard_True; | |
49cfd13d | 147 | else if (i < nbarg) |
148 | { | |
f2006a6f | 149 | if (aOpt == "-algo") |
46478ffe | 150 | { |
f2006a6f | 151 | TCollection_AsciiString anAlgoStr (argv[i++]); |
152 | anAlgoStr.LowerCase(); | |
153 | if (anAlgoStr == "watson" | |
154 | || anAlgoStr == "0") | |
155 | { | |
156 | aMeshParams.MeshAlgo = IMeshTools_MeshAlgoType_Watson; | |
157 | aContext->SetFaceDiscret (new BRepMesh_FaceDiscret (new BRepMesh_MeshAlgoFactory)); | |
158 | } | |
159 | else if (anAlgoStr == "delabella" | |
160 | || anAlgoStr == "1") | |
161 | { | |
162 | aMeshParams.MeshAlgo = IMeshTools_MeshAlgoType_Delabella; | |
163 | aContext->SetFaceDiscret (new BRepMesh_FaceDiscret (new BRepMesh_DelabellaMeshAlgoFactory)); | |
164 | } | |
165 | else if (anAlgoStr == "-1" | |
166 | || anAlgoStr == "default") | |
167 | { | |
168 | // already handled by BRepMesh_Context constructor | |
169 | //aMeshParams.MeshAlgo = IMeshTools_MeshAlgoType_DEFAULT; | |
170 | } | |
171 | else | |
172 | { | |
173 | di << "Syntax error at " << anAlgoStr; | |
174 | return 1; | |
175 | } | |
46478ffe | 176 | } |
f2006a6f | 177 | else |
46478ffe | 178 | { |
f2006a6f | 179 | Standard_Real aVal = Draw::Atof(argv[i++]); |
180 | if (aOpt == "-a") | |
181 | { | |
182 | aMeshParams.Angle = aVal * M_PI / 180.; | |
183 | } | |
184 | else if (aOpt == "-ai") | |
185 | { | |
186 | aMeshParams.AngleInterior = aVal * M_PI / 180.; | |
187 | } | |
188 | else if (aOpt == "-min") | |
189 | aMeshParams.MinSize = aVal; | |
190 | else if (aOpt == "-di") | |
191 | { | |
192 | aMeshParams.DeflectionInterior = aVal; | |
193 | } | |
194 | else | |
195 | --i; | |
46478ffe | 196 | } |
49cfd13d | 197 | } |
198 | } | |
416d4426 | 199 | } |
49cfd13d | 200 | |
416d4426 | 201 | di << "Incremental Mesh, multi-threading " |
7bd071ed | 202 | << (aMeshParams.InParallel ? "ON" : "OFF") << "\n"; |
203 | ||
ce97cd97 | 204 | Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1); |
f2006a6f | 205 | BRepMesh_IncrementalMesh aMesher; |
206 | aMesher.SetShape (aShape); | |
207 | aMesher.ChangeParameters() = aMeshParams; | |
208 | ||
209 | aMesher.Perform (aContext, aProgress->Start()); | |
d51c7072 | 210 | |
49cfd13d | 211 | di << "Meshing statuses: "; |
7bd071ed | 212 | const Standard_Integer aStatus = aMesher.GetStatusFlags(); |
213 | if (!aStatus) | |
d51c7072 O |
214 | { |
215 | di << "NoError"; | |
216 | } | |
217 | else | |
218 | { | |
219 | Standard_Integer i; | |
ce97cd97 | 220 | for (i = 0; i < 9; i++) |
d51c7072 | 221 | { |
7bd071ed | 222 | Standard_Integer aFlag = aStatus & (1 << i); |
223 | if (aFlag) | |
d51c7072 | 224 | { |
7bd071ed | 225 | switch ((IMeshData_Status) aFlag) |
d51c7072 | 226 | { |
7bd071ed | 227 | case IMeshData_OpenWire: |
228 | di << "OpenWire "; | |
229 | break; | |
230 | case IMeshData_SelfIntersectingWire: | |
231 | di << "SelfIntersectingWire "; | |
232 | break; | |
233 | case IMeshData_Failure: | |
234 | di << "Failure "; | |
235 | break; | |
236 | case IMeshData_ReMesh: | |
237 | di << "ReMesh "; | |
238 | break; | |
239 | case IMeshData_UnorientedWire: | |
240 | di << "UnorientedWire "; | |
241 | break; | |
242 | case IMeshData_TooFewPoints: | |
243 | di << "TooFewPoints "; | |
244 | break; | |
245 | case IMeshData_Outdated: | |
246 | di << "Outdated "; | |
247 | break; | |
248 | case IMeshData_Reused: | |
249 | di << "Reused "; | |
250 | break; | |
ce97cd97 | 251 | case IMeshData_UserBreak: |
252 | di << "User break"; | |
253 | break; | |
7bd071ed | 254 | case IMeshData_NoError: |
255 | default: | |
256 | break; | |
d51c7072 O |
257 | } |
258 | } | |
259 | } | |
260 | } | |
261 | ||
7fd59977 | 262 | return 0; |
263 | } | |
264 | ||
265 | //======================================================================= | |
b508cbc5 | 266 | //function : tessellate |
267 | //purpose : | |
268 | //======================================================================= | |
269 | static Standard_Integer tessellate (Draw_Interpretor& /*di*/, Standard_Integer nbarg, const char** argv) | |
270 | { | |
271 | if (nbarg != 5) | |
272 | { | |
d99f0355 | 273 | Message::SendFail() << "Builds regular triangulation with specified number of triangles\n" |
b508cbc5 | 274 | " Usage: tessellate result {surface|face} nbu nbv\n" |
275 | " Triangulation is put into the face with natural bounds (result);\n" | |
276 | " it will have 2*nbu*nbv triangles and (nbu+1)*(nbv+1) nodes"; | |
277 | return 1; | |
278 | } | |
279 | ||
280 | const char *aResName = argv[1]; | |
281 | const char *aSrcName = argv[2]; | |
282 | int aNbU = Draw::Atoi (argv[3]); | |
283 | int aNbV = Draw::Atoi (argv[4]); | |
284 | ||
285 | if (aNbU <= 0 || aNbV <= 0) | |
286 | { | |
d99f0355 | 287 | Message::SendFail() << "Error: Arguments nbu and nbv must be both greater than 0"; |
b508cbc5 | 288 | return 1; |
289 | } | |
290 | ||
291 | Handle(Geom_Surface) aSurf = DrawTrSurf::GetSurface(aSrcName); | |
292 | double aUMin, aUMax, aVMin, aVMax; | |
293 | if (! aSurf.IsNull()) | |
294 | { | |
295 | aSurf->Bounds (aUMin, aUMax, aVMin, aVMax); | |
296 | } | |
297 | else | |
298 | { | |
299 | TopoDS_Shape aShape = DBRep::Get(aSrcName); | |
300 | if (aShape.IsNull() || aShape.ShapeType() != TopAbs_FACE) | |
301 | { | |
d99f0355 | 302 | Message::SendFail() << "Error: " << aSrcName << " is not a face"; |
b508cbc5 | 303 | return 1; |
304 | } | |
305 | TopoDS_Face aFace = TopoDS::Face (aShape); | |
306 | aSurf = BRep_Tool::Surface (aFace); | |
307 | if (aSurf.IsNull()) | |
308 | { | |
d99f0355 | 309 | Message::SendFail() << "Error: Face " << aSrcName << " has no surface"; |
b508cbc5 | 310 | return 1; |
311 | } | |
312 | ||
313 | BRepTools::UVBounds (aFace, aUMin, aUMax, aVMin, aVMax); | |
314 | } | |
315 | if (Precision::IsInfinite (aUMin) || Precision::IsInfinite (aUMax) || | |
316 | Precision::IsInfinite (aVMin) || Precision::IsInfinite (aVMax)) | |
317 | { | |
d99f0355 | 318 | Message::SendFail() << "Error: surface has infinite parametric range, aborting"; |
b508cbc5 | 319 | return 1; |
320 | } | |
321 | ||
322 | BRepBuilderAPI_MakeFace aFaceMaker (aSurf, aUMin, aUMax, aVMin, aVMax, Precision::Confusion()); | |
323 | if (! aFaceMaker.IsDone()) | |
324 | { | |
d99f0355 | 325 | Message::SendFail() << "Error: cannot build face with natural bounds, aborting"; |
b508cbc5 | 326 | return 1; |
327 | } | |
328 | TopoDS_Face aFace = aFaceMaker; | |
329 | ||
330 | // create triangulation | |
331 | int aNbNodes = (aNbU + 1) * (aNbV + 1); | |
332 | int aNbTriangles = 2 * aNbU * aNbV; | |
333 | Handle(Poly_Triangulation) aTriangulation = | |
334 | new Poly_Triangulation (aNbNodes, aNbTriangles, Standard_False); | |
335 | ||
336 | // fill nodes | |
337 | TColgp_Array1OfPnt &aNodes = aTriangulation->ChangeNodes(); | |
338 | GeomAdaptor_Surface anAdSurf (aSurf); | |
339 | double aDU = (aUMax - aUMin) / aNbU; | |
340 | double aDV = (aVMax - aVMin) / aNbV; | |
341 | for (int iU = 0, iShift = 1; iU <= aNbU; iU++, iShift += aNbV + 1) | |
342 | { | |
343 | double aU = aUMin + iU * aDU; | |
344 | for (int iV = 0; iV <= aNbV; iV++) | |
345 | { | |
346 | double aV = aVMin + iV * aDV; | |
347 | gp_Pnt aP = anAdSurf.Value (aU, aV); | |
348 | aNodes.SetValue (iShift + iV, aP); | |
349 | } | |
350 | } | |
351 | ||
352 | // fill triangles | |
353 | Poly_Array1OfTriangle &aTriangles = aTriangulation->ChangeTriangles(); | |
354 | for (int iU = 0, iShift = 1, iTri = 0; iU < aNbU; iU++, iShift += aNbV + 1) | |
355 | { | |
356 | for (int iV = 0; iV < aNbV; iV++) | |
357 | { | |
358 | int iBase = iShift + iV; | |
359 | Poly_Triangle aTri1 (iBase, iBase + aNbV + 2, iBase + 1); | |
360 | Poly_Triangle aTri2 (iBase, iBase + aNbV + 1, iBase + aNbV + 2); | |
361 | aTriangles.SetValue (++iTri, aTri1); | |
362 | aTriangles.SetValue (++iTri, aTri2); | |
363 | } | |
364 | } | |
365 | ||
366 | // put triangulation to face | |
367 | BRep_Builder B; | |
368 | B.UpdateFace (aFace, aTriangulation); | |
369 | ||
370 | // fill edge polygons | |
371 | TColStd_Array1OfInteger aUMinIso (1, aNbV + 1), aUMaxIso (1, aNbV + 1); | |
372 | for (int iV = 0; iV <= aNbV; iV++) | |
373 | { | |
374 | aUMinIso.SetValue (1 + iV, 1 + iV); | |
375 | aUMaxIso.SetValue (1 + iV, 1 + iV + aNbU * (1 + aNbV)); | |
376 | } | |
377 | TColStd_Array1OfInteger aVMinIso (1, aNbU + 1), aVMaxIso (1, aNbU + 1); | |
378 | for (int iU = 0; iU <= aNbU; iU++) | |
379 | { | |
380 | aVMinIso.SetValue (1 + iU, 1 + iU * (1 + aNbV)); | |
381 | aVMaxIso.SetValue (1 + iU, (1 + iU) * (1 + aNbV)); | |
382 | } | |
383 | Handle(Poly_PolygonOnTriangulation) aUMinPoly = new Poly_PolygonOnTriangulation (aUMinIso); | |
384 | Handle(Poly_PolygonOnTriangulation) aUMaxPoly = new Poly_PolygonOnTriangulation (aUMaxIso); | |
385 | Handle(Poly_PolygonOnTriangulation) aVMinPoly = new Poly_PolygonOnTriangulation (aVMinIso); | |
386 | Handle(Poly_PolygonOnTriangulation) aVMaxPoly = new Poly_PolygonOnTriangulation (aVMaxIso); | |
387 | for (TopExp_Explorer exp (aFace, TopAbs_EDGE); exp.More(); exp.Next()) | |
388 | { | |
389 | TopoDS_Edge anEdge = TopoDS::Edge (exp.Current()); | |
390 | Standard_Real aFirst, aLast; | |
391 | Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface (anEdge, aFace, aFirst, aLast); | |
392 | gp_Pnt2d aPFirst = aC->Value (aFirst); | |
393 | gp_Pnt2d aPLast = aC->Value (aLast); | |
394 | if (Abs (aPFirst.X() - aPLast.X()) < 0.1 * (aUMax - aUMin)) // U=const | |
395 | { | |
396 | if (BRep_Tool::IsClosed (anEdge, aFace)) | |
397 | B.UpdateEdge (anEdge, aUMinPoly, aUMaxPoly, aTriangulation); | |
398 | else | |
399 | B.UpdateEdge (anEdge, (aPFirst.X() < 0.5 * (aUMin + aUMax) ? aUMinPoly : aUMaxPoly), aTriangulation); | |
400 | } | |
401 | else // V=const | |
402 | { | |
403 | if (BRep_Tool::IsClosed (anEdge, aFace)) | |
404 | B.UpdateEdge (anEdge, aVMinPoly, aVMaxPoly, aTriangulation); | |
405 | else | |
406 | B.UpdateEdge (anEdge, (aPFirst.Y() < 0.5 * (aVMin + aVMax) ? aVMinPoly : aVMaxPoly), aTriangulation); | |
407 | } | |
408 | } | |
409 | ||
410 | DBRep::Set (aResName, aFace); | |
411 | return 0; | |
412 | } | |
413 | ||
414 | //======================================================================= | |
7fd59977 | 415 | //function : MemLeakTest |
416 | //purpose : | |
417 | //======================================================================= | |
35e08fe8 | 418 | static Standard_Integer MemLeakTest(Draw_Interpretor&, Standard_Integer /*nbarg*/, const char** /*argv*/) |
7fd59977 | 419 | { |
420 | for(int i=0;i<10000;i++) | |
421 | { | |
422 | BRepBuilderAPI_MakePolygon w(gp_Pnt(0,0,0),gp_Pnt(0,100,0),gp_Pnt(20,100,0),gp_Pnt(20,0,0)); | |
423 | w.Close(); | |
424 | TopoDS_Wire wireShape( w.Wire()); | |
425 | BRepBuilderAPI_MakeFace faceBuilder(wireShape); | |
426 | TopoDS_Face f( faceBuilder.Face()); | |
427 | BRepMesh_IncrementalMesh im(f,1); | |
428 | BRepTools::Clean(f); | |
429 | } | |
430 | return 0; | |
431 | } | |
432 | ||
433 | //======================================================================= | |
7fd59977 | 434 | //function : trianglesinfo |
435 | //purpose : | |
436 | //======================================================================= | |
437 | static Standard_Integer trianglesinfo(Draw_Interpretor& di, Standard_Integer n, const char** a) | |
438 | { | |
439 | if (n != 2) return 1; | |
440 | TopoDS_Shape S = DBRep::Get(a[1]); | |
441 | if (S.IsNull()) return 1; | |
442 | TopExp_Explorer ex; | |
443 | Handle(Poly_Triangulation) T; | |
444 | TopLoc_Location L; | |
445 | ||
446 | Standard_Real MaxDeflection = 0.0; | |
5bae0beb | 447 | Standard_Integer nbtriangles = 0, nbnodes = 0, nbrepresentations = 0; |
7fd59977 | 448 | for (ex.Init(S, TopAbs_FACE); ex.More(); ex.Next()) { |
449 | TopoDS_Face F = TopoDS::Face(ex.Current()); | |
450 | T = BRep_Tool::Triangulation(F, L); | |
451 | if (!T.IsNull()) { | |
452 | nbtriangles += T->NbTriangles(); | |
453 | nbnodes += T->NbNodes(); | |
454 | if (T->Deflection() > MaxDeflection) | |
455 | MaxDeflection = T->Deflection(); | |
456 | } | |
457 | } | |
5bae0beb | 458 | TopTools_IndexedMapOfShape anEdges; |
459 | TopExp::MapShapes(S, TopAbs_EDGE, anEdges); | |
460 | for (int i = 1; i<=anEdges.Extent(); ++i) | |
461 | { | |
462 | const TopoDS_Edge& anEdge = TopoDS::Edge(anEdges(i)); | |
463 | Handle(BRep_CurveRepresentation) aCR; | |
464 | BRep_TEdge* aTE = static_cast<BRep_TEdge*>(anEdge.TShape().get()); | |
465 | const BRep_ListOfCurveRepresentation& aLCR = aTE->Curves(); | |
466 | BRep_ListIteratorOfListOfCurveRepresentation anIterCR(aLCR); | |
467 | ||
468 | while (anIterCR.More()) { | |
469 | aCR = anIterCR.Value(); | |
470 | if (aCR->IsPolygonOnTriangulation()) | |
471 | { | |
472 | nbrepresentations++; | |
473 | } | |
474 | anIterCR.Next(); | |
475 | } | |
476 | } | |
7fd59977 | 477 | |
478 | di<<"\n"; | |
5bae0beb | 479 | di << "This shape contains " << nbtriangles << " triangles.\n"; |
480 | di << " " << nbnodes << " nodes.\n"; | |
481 | di << " " << nbrepresentations << " polygons on triangulation .\n";; | |
482 | di << "Maximal deflection " << MaxDeflection << "\n"; | |
483 | ||
7fd59977 | 484 | di<<"\n"; |
0797d9d3 | 485 | #ifdef OCCT_DEBUG_MESH_CHRONO |
7fd59977 | 486 | Standard_Real tot, addp, unif, contr, inter; |
487 | Standard_Real edges, mailledges, etuinter, lastcontrol, stock; | |
488 | Standard_Real add11, add12, add2, upda, pointvalid; | |
489 | Standard_Real isos, pointsisos; | |
490 | chTotal.Show(tot); chAddPoint.Show(addp); chUnif.Show(unif); | |
491 | chControl.Show(contr); chInternal.Show(inter); | |
492 | chEdges.Show(edges); chMaillEdges.Show(mailledges); | |
493 | chEtuInter.Show(etuinter); chLastControl.Show(lastcontrol); | |
494 | chStock.Show(stock); | |
495 | chAdd11.Show(add11); chAdd12.Show(add12); chAdd2.Show(add2); chUpdate.Show(upda); | |
496 | chPointValid.Show(pointvalid); chIsos.Show(isos); chPointsOnIsos.Show(pointsisos); | |
497 | ||
498 | if (tot > 0.00001) { | |
586db386 | 499 | di <<"temps total de maillage: "<<tot <<" seconds\n"; |
500 | di <<"dont: \n"; | |
501 | di <<"discretisation des edges: "<<edges <<" seconds---> "<< 100*edges/tot <<" %\n"; | |
502 | di <<"maillage des edges: "<<mailledges <<" seconds---> "<< 100*mailledges/tot <<" %\n"; | |
503 | di <<"controle et points internes: "<<etuinter <<" seconds---> "<< 100*etuinter/tot <<" %\n"; | |
504 | di <<"derniers controles: "<<lastcontrol<<" seconds---> "<< 100*lastcontrol/tot<<" %\n"; | |
505 | di <<"stockage dans la S.D. "<<stock <<" seconds---> "<< 100*stock/tot <<" %\n"; | |
0d88155b | 506 | di << "\n"; |
586db386 | 507 | di <<"et plus precisement: \n"; |
508 | di <<"Add 11ere partie : "<<add11 <<" seconds---> "<<100*add11/tot <<" %\n"; | |
509 | di <<"Add 12ere partie : "<<add12 <<" seconds---> "<<100*add12/tot <<" %\n"; | |
510 | di <<"Add 2eme partie : "<<add2 <<" seconds---> "<<100*add2/tot <<" %\n"; | |
511 | di <<"Update : "<<upda <<" seconds---> "<<100*upda/tot <<" %\n"; | |
512 | di <<"AddPoint : "<<addp <<" seconds---> "<<100*addp/tot <<" %\n"; | |
513 | di <<"UniformDeflection "<<unif <<" seconds---> "<<100*unif/tot <<" %\n"; | |
514 | di <<"Controle : "<<contr <<" seconds---> "<<100*contr/tot <<" %\n"; | |
515 | di <<"Points Internes: "<<inter <<" seconds---> "<<100*inter/tot <<" %\n"; | |
516 | di <<"calcul des isos et du, dv: "<<isos <<" seconds---> "<<100*isos/tot <<" %\n"; | |
517 | di <<"calcul des points sur isos: "<<pointsisos<<" seconds---> "<<100*pointsisos/tot <<" %\n"; | |
518 | di <<"IsPointValid: "<<pointvalid<<" seconds---> "<<100*pointvalid/tot <<" %\n"; | |
0d88155b O |
519 | di << "\n"; |
520 | ||
521 | ||
522 | di <<"nombre d'appels de controle apres points internes : "<< NbControls << "\n"; | |
523 | di <<"nombre de points sur restrictions : "<< D0Edges << "\n"; | |
524 | di <<"nombre de points calcules par UniformDeflection : "<< D0Unif << "\n"; | |
525 | di <<"nombre de points calcules dans InternalVertices : "<< D0Internal << "\n"; | |
526 | di <<"nombre de points calcules dans Control : "<< D0Control << "\n"; | |
527 | if (nbnodes-D0Edges != 0) { | |
528 | Standard_Real ratio = (Standard_Real)(D0Internal+D0Control)/ (Standard_Real)(nbnodes-D0Edges); | |
529 | di <<"---> Ratio: (D0Internal+D0Control) / (nbNodes-nbOnEdges) : "<< ratio << "\n"; | |
530 | } | |
7fd59977 | 531 | |
0d88155b | 532 | di << "\n"; |
7fd59977 | 533 | |
0d88155b O |
534 | chTotal.Reset(); chAddPoint.Reset(); chUnif.Reset(); |
535 | chControl.Reset(); chInternal.Reset(); | |
536 | chEdges.Reset(); chMaillEdges.Reset(); | |
537 | chEtuInter.Reset(); chLastControl.Reset(); | |
538 | chStock.Reset(); | |
539 | chAdd11.Reset(); chAdd12.Reset(); chAdd2.Reset(); chUpdate.Reset(); | |
540 | chPointValid.Reset(); chIsos.Reset(); chPointsOnIsos.Reset(); | |
7fd59977 | 541 | |
542 | } | |
543 | #endif | |
544 | return 0; | |
545 | } | |
546 | ||
547 | //======================================================================= | |
548 | //function : veriftriangles | |
549 | //purpose : | |
550 | //======================================================================= | |
7fd59977 | 551 | static Standard_Integer veriftriangles(Draw_Interpretor& di, Standard_Integer n, const char** a) |
552 | { | |
553 | if (n < 2) return 1; | |
554 | Standard_Boolean quiet = 1; | |
555 | if (n == 3) quiet = 0; | |
556 | TopoDS_Shape Sh = DBRep::Get(a[1]); | |
557 | if (Sh.IsNull()) return 1; | |
558 | TopExp_Explorer ex; | |
559 | Handle(Poly_Triangulation) T; | |
560 | TopLoc_Location L; | |
561 | Standard_Integer i, n1, n2, n3; | |
562 | gp_Pnt2d mitri, v1, v2, v3, mi2d1, mi2d2, mi2d3; | |
563 | gp_XYZ vecEd1, vecEd2, vecEd3; | |
0d88155b | 564 | // Standard_Real dipo, dm, dv, d1, d2, d3, defle; |
7fd59977 | 565 | Standard_Real dipo, dv, d1, d2, d3, defle; |
566 | Handle(Geom_Surface) S; | |
567 | Standard_Integer nbface = 0; | |
568 | gp_Pnt PP; | |
569 | ||
570 | for (ex.Init(Sh, TopAbs_FACE); ex.More(); ex.Next()) { | |
571 | TopoDS_Face F = TopoDS::Face(ex.Current()); | |
572 | nbface++; | |
573 | T = BRep_Tool::Triangulation(F, L); | |
574 | Standard_Real deflemax = 0, deflemin = 1.e100; | |
575 | if (!T.IsNull()) { | |
576 | Standard_Real defstock = T->Deflection(); | |
577 | const Poly_Array1OfTriangle& triangles = T->Triangles(); | |
578 | const TColgp_Array1OfPnt2d& Nodes2d = T->UVNodes(); | |
579 | const TColgp_Array1OfPnt& Nodes = T->Nodes(); | |
580 | ||
581 | S = BRep_Tool::Surface(F, L); | |
582 | ||
583 | for(i = 1; i <= triangles.Length(); i++) { | |
0d88155b O |
584 | if (F.Orientation() == TopAbs_REVERSED) |
585 | triangles(i).Get(n1,n3,n2); | |
586 | else | |
587 | triangles(i).Get(n1,n2,n3); | |
588 | ||
589 | const gp_XY& xy1 = Nodes2d(n1).XY(); | |
590 | const gp_XY& xy2 = Nodes2d(n2).XY(); | |
591 | const gp_XY& xy3 = Nodes2d(n3).XY(); | |
592 | ||
593 | mi2d1.SetCoord((xy2.X()+xy3.X())*0.5, | |
594 | (xy2.Y()+xy3.Y())*0.5); | |
595 | mi2d2.SetCoord((xy1.X()+xy3.X())*0.5, | |
596 | (xy1.Y()+xy3.Y())*0.5); | |
597 | mi2d3.SetCoord((xy1.X()+xy2.X())*0.5, | |
598 | (xy1.Y()+xy2.Y())*0.5); | |
599 | ||
600 | gp_XYZ p1 = Nodes(n1).Transformed(L.Transformation()).XYZ(); | |
601 | gp_XYZ p2 = Nodes(n2).Transformed(L.Transformation()).XYZ(); | |
602 | gp_XYZ p3 = Nodes(n3).Transformed(L.Transformation()).XYZ(); | |
603 | ||
604 | vecEd1=p2-p1; | |
605 | vecEd2=p3-p2; | |
606 | vecEd3=p1-p3; | |
607 | d1=vecEd1.SquareModulus(); | |
608 | d2=vecEd2.SquareModulus(); | |
609 | d3=vecEd3.SquareModulus(); | |
610 | ||
611 | if (d1!=0. && d2!=0. && d3!=0.) { | |
612 | gp_XYZ equa(vecEd1^vecEd2); | |
613 | dv=equa.Modulus(); | |
614 | if (dv>0.) { | |
615 | equa.SetCoord(equa.X()/dv, equa.Y()/dv, equa.Z()/dv); | |
616 | dipo=equa*p1; | |
617 | ||
618 | ||
619 | mitri.SetCoord(ONETHIRD*(xy1.X()+xy2.X()+xy3.X()), | |
620 | ONETHIRD*(xy1.Y()+xy2.Y()+xy3.Y())); | |
621 | v1.SetCoord(ONETHIRD*mi2d1.X()+TWOTHIRD*xy1.X(), | |
622 | ONETHIRD*mi2d1.Y()+TWOTHIRD*xy1.Y()); | |
623 | v2.SetCoord(ONETHIRD*mi2d2.X()+TWOTHIRD*xy2.X(), | |
624 | ONETHIRD*mi2d2.Y()+TWOTHIRD*xy2.Y()); | |
625 | v3.SetCoord(ONETHIRD*mi2d3.X()+TWOTHIRD*xy3.X(), | |
626 | ONETHIRD*mi2d3.Y()+TWOTHIRD*xy3.Y()); | |
627 | ||
628 | S->D0(mi2d1.X(), mi2d1.Y(), PP); | |
629 | PP = PP.Transformed(L.Transformation()); | |
630 | defle = Abs((equa*PP.XYZ())-dipo); | |
631 | deflemax = Max(deflemax, defle); | |
632 | deflemin = Min(deflemin, defle); | |
633 | ||
634 | S->D0(mi2d2.X(), mi2d2.Y(), PP); | |
635 | PP = PP.Transformed(L.Transformation()); | |
636 | defle = Abs((equa*PP.XYZ())-dipo); | |
637 | deflemax = Max(deflemax, defle); | |
638 | deflemin = Min(deflemin, defle); | |
639 | ||
640 | S->D0(mi2d3.X(), mi2d3.Y(), PP); | |
641 | PP = PP.Transformed(L.Transformation()); | |
642 | defle = Abs((equa*PP.XYZ())-dipo); | |
643 | deflemax = Max(deflemax, defle); | |
644 | deflemin = Min(deflemin, defle); | |
645 | ||
646 | S->D0(v1.X(), v1.Y(), PP); | |
647 | PP = PP.Transformed(L.Transformation()); | |
648 | defle = Abs((equa*PP.XYZ())-dipo); | |
649 | deflemax = Max(deflemax, defle); | |
650 | deflemin = Min(deflemin, defle); | |
651 | ||
652 | S->D0(v2.X(), v2.Y(), PP); | |
653 | PP = PP.Transformed(L.Transformation()); | |
654 | defle = Abs((equa*PP.XYZ())-dipo); | |
655 | deflemax = Max(deflemax, defle); | |
656 | deflemin = Min(deflemin, defle); | |
657 | ||
658 | S->D0(v3.X(), v3.Y(), PP); | |
659 | PP = PP.Transformed(L.Transformation()); | |
660 | defle = Abs((equa*PP.XYZ())-dipo); | |
661 | deflemax = Max(deflemax, defle); | |
662 | deflemin = Min(deflemin, defle); | |
663 | ||
664 | S->D0(mitri.X(), mitri.Y(), PP); | |
665 | PP = PP.Transformed(L.Transformation()); | |
666 | defle = Abs((equa*PP.XYZ())-dipo); | |
667 | deflemax = Max(deflemax, defle); | |
668 | deflemin = Min(deflemin, defle); | |
669 | ||
670 | if (defle > defstock) { | |
586db386 | 671 | di <<"face "<< nbface <<" deflection = " << defle <<" pour "<<defstock <<" stockee.\n"; |
0d88155b O |
672 | } |
673 | } | |
674 | } | |
7fd59977 | 675 | } |
676 | if (!quiet) { | |
0d88155b | 677 | di <<"face "<< nbface<<", deflemin = "<< deflemin<<", deflemax = "<<deflemax<<"\n"; |
7fd59977 | 678 | } |
679 | ||
680 | } | |
681 | } | |
682 | ||
683 | ||
684 | return 0; | |
685 | } | |
686 | ||
7fd59977 | 687 | //======================================================================= |
688 | //function : tri2d | |
689 | //purpose : | |
690 | //======================================================================= | |
4006ca98 | 691 | static Standard_Integer tri2d(Draw_Interpretor&, Standard_Integer n, const char** a) |
7fd59977 | 692 | { |
693 | ||
694 | if (n != 2) return 1; | |
695 | TopoDS_Shape aLocalShape = DBRep::Get(a[1]); | |
696 | TopoDS_Face F = TopoDS::Face(aLocalShape); | |
0d88155b | 697 | // TopoDS_Face F = TopoDS::Face(DBRep::Get(a[1])); |
7fd59977 | 698 | if (F.IsNull()) return 1; |
699 | Handle(Poly_Triangulation) T; | |
700 | TopLoc_Location L; | |
701 | ||
702 | T = BRep_Tool::Triangulation(F, L); | |
703 | if (!T.IsNull()) { | |
7fd59977 | 704 | // Build the connect tool |
705 | Poly_Connect pc(T); | |
0d88155b | 706 | |
7fd59977 | 707 | Standard_Integer i,j, nFree, nInternal, nbTriangles = T->NbTriangles(); |
708 | Standard_Integer t[3]; | |
0d88155b | 709 | |
7fd59977 | 710 | // count the free edges |
711 | nFree = 0; | |
712 | for (i = 1; i <= nbTriangles; i++) { | |
713 | pc.Triangles(i,t[0],t[1],t[2]); | |
714 | for (j = 0; j < 3; j++) | |
0d88155b | 715 | if (t[j] == 0) nFree++; |
7fd59977 | 716 | } |
0d88155b | 717 | |
7fd59977 | 718 | // allocate the arrays |
719 | TColStd_Array1OfInteger Free(1,2*nFree); | |
720 | nInternal = (3*nbTriangles - nFree) / 2; | |
721 | TColStd_Array1OfInteger Internal(0,2*nInternal); | |
0d88155b | 722 | |
7fd59977 | 723 | Standard_Integer fr = 1, in = 1; |
724 | const Poly_Array1OfTriangle& triangles = T->Triangles(); | |
725 | Standard_Integer nodes[3]; | |
726 | for (i = 1; i <= nbTriangles; i++) { | |
727 | pc.Triangles(i,t[0],t[1],t[2]); | |
728 | triangles(i).Get(nodes[0],nodes[1],nodes[2]); | |
729 | for (j = 0; j < 3; j++) { | |
0d88155b O |
730 | Standard_Integer k = (j+1) % 3; |
731 | if (t[j] == 0) { | |
732 | Free(fr) = nodes[j]; | |
733 | Free(fr+1) = nodes[k]; | |
734 | fr += 2; | |
735 | } | |
736 | // internal edge if this triangle has a lower index than the adjacent | |
737 | else if (i < t[j]) { | |
738 | Internal(in) = nodes[j]; | |
739 | Internal(in+1) = nodes[k]; | |
740 | in += 2; | |
741 | } | |
7fd59977 | 742 | } |
743 | } | |
0d88155b | 744 | |
7fd59977 | 745 | // Display the edges |
746 | if (T->HasUVNodes()) { | |
747 | const TColgp_Array1OfPnt2d& Nodes2d = T->UVNodes(); | |
748 | ||
749 | Handle(Draw_Segment2D) Seg; | |
750 | ||
751 | // free edges | |
752 | Standard_Integer nn; | |
753 | nn = Free.Length() / 2; | |
754 | for (i = 1; i <= nn; i++) { | |
0d88155b O |
755 | Seg = new Draw_Segment2D(Nodes2d(Free(2*i-1)), |
756 | Nodes2d(Free(2*i)), | |
757 | Draw_rouge); | |
758 | dout << Seg; | |
7fd59977 | 759 | } |
0d88155b | 760 | |
7fd59977 | 761 | // internal edges |
0d88155b | 762 | |
7fd59977 | 763 | nn = nInternal; |
764 | for (i = 1; i <= nn; i++) { | |
0d88155b O |
765 | Seg = new Draw_Segment2D(Nodes2d(Internal(2*i-1)), |
766 | Nodes2d(Internal(2*i)), | |
767 | Draw_bleu); | |
768 | dout << Seg; | |
7fd59977 | 769 | } |
770 | } | |
771 | dout.Flush(); | |
772 | } | |
773 | ||
774 | return 0; | |
775 | } | |
776 | ||
7fd59977 | 777 | //======================================================================= |
778 | //function : wavefront | |
779 | //purpose : | |
780 | //======================================================================= | |
7fd59977 | 781 | static Standard_Integer wavefront(Draw_Interpretor&, Standard_Integer nbarg, const char** argv) |
782 | { | |
783 | if (nbarg < 2) return 1; | |
784 | ||
785 | TopoDS_Shape S = DBRep::Get(argv[1]); | |
786 | if (S.IsNull()) return 1; | |
787 | ||
788 | // creation du maillage s'il n'existe pas. | |
789 | ||
790 | Bnd_Box B; | |
791 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; | |
792 | BRepBndLib::Add(S, B); | |
793 | B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); | |
794 | Standard_Real aDeflection = | |
795 | MAX3( aXmax-aXmin , aYmax-aYmin , aZmax-aZmin) * 0.004; | |
796 | ||
b3a7aa39 | 797 | BRepMesh_IncrementalMesh aMesh (S, aDeflection); |
7fd59977 | 798 | |
799 | ||
800 | TopLoc_Location L; | |
801 | TopExp_Explorer ex; | |
802 | ||
803 | Standard_Integer i, nbface = 0; | |
804 | Standard_Boolean OK = Standard_True; | |
805 | gp_Vec D1U,D1V; | |
806 | gp_Vec D2U,D2V,D2UV; | |
807 | gp_Dir Nor; | |
808 | gp_Pnt P; | |
809 | Standard_Real U, V; | |
9fd2d2c3 | 810 | CSLib_DerivativeStatus aStatus; |
7fd59977 | 811 | CSLib_NormalStatus NStat; |
812 | Standard_Real x, y, z; | |
813 | Standard_Integer n1, n2, n3; | |
814 | Standard_Integer k1, k2, k3; | |
0d88155b | 815 | |
84d0342c | 816 | TCollection_AsciiString aFile; |
0d88155b | 817 | |
7fd59977 | 818 | if (nbarg == 3) { |
84d0342c | 819 | aFile = argv[2]; |
820 | aFile += ".obj"; | |
7fd59977 | 821 | } |
84d0342c | 822 | else aFile = "wave.obj"; |
823 | FILE* outfile = OSD_OpenFile(aFile.ToCString(), "w"); | |
7fd59977 | 824 | |
825 | ||
84d0342c | 826 | fprintf(outfile, "%s %s\n%s %s\n\n", "# CASCADE ","MATRA DATAVISION", "#", aFile.ToCString()); |
7fd59977 | 827 | |
828 | Standard_Integer nbNodes, totalnodes = 0, nbpolygons = 0; | |
829 | for (ex.Init(S, TopAbs_FACE); ex.More(); ex.Next()) { | |
830 | nbface++; | |
831 | TopoDS_Face F = TopoDS::Face(ex.Current()); | |
832 | Handle(Poly_Triangulation) Tr = BRep_Tool::Triangulation(F, L); | |
0d88155b | 833 | |
7fd59977 | 834 | if (!Tr.IsNull()) { |
835 | nbNodes = Tr->NbNodes(); | |
836 | const TColgp_Array1OfPnt& Nodes = Tr->Nodes(); | |
0d88155b | 837 | |
7fd59977 | 838 | // les noeuds. |
839 | for (i = 1; i <= nbNodes; i++) { | |
0d88155b O |
840 | gp_Pnt Pnt = Nodes(i).Transformed(L.Transformation()); |
841 | x = Pnt.X(); | |
842 | y = Pnt.Y(); | |
843 | z = Pnt.Z(); | |
844 | fprintf(outfile, "%s %f %f %f\n", "v", x, y, z); | |
7fd59977 | 845 | } |
0d88155b | 846 | |
7fd59977 | 847 | fprintf(outfile, "\n%s %d\n\n", "# number of vertex", nbNodes); |
0d88155b O |
848 | |
849 | ||
7fd59977 | 850 | // les normales. |
0d88155b | 851 | |
7fd59977 | 852 | if (Tr->HasUVNodes()) { |
0d88155b O |
853 | const TColgp_Array1OfPnt2d& UVNodes = Tr->UVNodes(); |
854 | BRepAdaptor_Surface BS(F, Standard_False); | |
855 | ||
856 | for (i = 1; i <= nbNodes; i++) { | |
857 | U = UVNodes(i).X(); | |
858 | V = UVNodes(i).Y(); | |
859 | ||
860 | BS.D1(U,V,P,D1U,D1V); | |
9fd2d2c3 | 861 | CSLib::Normal (D1U, D1V, Precision::Angular(), aStatus, Nor); |
862 | if (aStatus != CSLib_Done) { | |
0d88155b O |
863 | BS.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); |
864 | CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor); | |
865 | } | |
866 | if (F.Orientation() == TopAbs_REVERSED) Nor.Reverse(); | |
867 | ||
868 | fprintf(outfile, "%s %f %f %f\n", "vn", Nor.X(), Nor.Y(), Nor.Z()); | |
869 | } | |
870 | ||
871 | fprintf(outfile, "\n%s %d\n\n", "# number of vertex normals", nbNodes); | |
7fd59977 | 872 | } |
0d88155b | 873 | |
7fd59977 | 874 | fprintf(outfile, "%s %d\n", "s", nbface); |
0d88155b | 875 | |
7fd59977 | 876 | // les triangles. |
877 | Standard_Integer nbTriangles = Tr->NbTriangles(); | |
878 | const Poly_Array1OfTriangle& triangles = Tr->Triangles(); | |
0d88155b O |
879 | |
880 | ||
7fd59977 | 881 | for (i = 1; i <= nbTriangles; i++) { |
0d88155b O |
882 | if (F.Orientation() == TopAbs_REVERSED) |
883 | triangles(i).Get(n1, n3, n2); | |
884 | else | |
885 | triangles(i).Get(n1, n2, n3); | |
886 | k1 = n1+totalnodes; | |
887 | k2 = n2+totalnodes; | |
888 | k3 = n3+totalnodes; | |
6b467e52 | 889 | fprintf(outfile, "f %d%s%d %d%s%d %d%s%d\n", k1,"//", k1, k2,"//", k2, k3,"//", k3); |
7fd59977 | 890 | } |
891 | nbpolygons += nbTriangles; | |
892 | totalnodes += nbNodes; | |
0d88155b | 893 | |
7fd59977 | 894 | fprintf(outfile, "\n%s %d\n", "# number of smooth groups", nbface); |
895 | fprintf(outfile, "\n%s %d\n", "# number of polygons", nbpolygons); | |
0d88155b | 896 | |
7fd59977 | 897 | } |
898 | } | |
899 | ||
900 | fclose(outfile); | |
901 | ||
902 | return 0; | |
903 | } | |
904 | ||
d51c7072 O |
905 | //======================================================================= |
906 | //function : triedgepoints | |
907 | //purpose : | |
908 | //======================================================================= | |
4006ca98 | 909 | static Standard_Integer triedgepoints(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv) |
d51c7072 O |
910 | { |
911 | if( nbarg < 2 ) | |
912 | return 1; | |
7fd59977 | 913 | |
d51c7072 O |
914 | for( Standard_Integer i = 1; i < nbarg; i++ ) |
915 | { | |
916 | TopoDS_Shape aShape = DBRep::Get(argv[i]); | |
917 | if ( aShape.IsNull() ) | |
918 | continue; | |
919 | ||
920 | Handle(Poly_PolygonOnTriangulation) aPoly; | |
921 | Handle(Poly_Triangulation) aT; | |
922 | TopLoc_Location aLoc; | |
923 | TopTools_MapOfShape anEdgeMap; | |
924 | TopTools_MapIteratorOfMapOfShape it; | |
925 | ||
926 | if( aShape.ShapeType() == TopAbs_EDGE ) | |
927 | { | |
928 | anEdgeMap.Add( aShape ); | |
929 | } | |
930 | else | |
931 | { | |
932 | TopExp_Explorer ex(aShape, TopAbs_EDGE); | |
933 | for(; ex.More(); ex.Next() ) | |
934 | anEdgeMap.Add( ex.Current() ); | |
935 | } | |
936 | ||
937 | if ( anEdgeMap.Extent() == 0 ) | |
938 | continue; | |
939 | ||
940 | char newname[1024]; | |
941 | strcpy(newname,argv[i]); | |
942 | char* p = newname; | |
943 | while (*p != '\0') p++; | |
944 | *p = '_'; | |
945 | p++; | |
946 | ||
947 | Standard_Integer nbEdge = 1; | |
948 | for(it.Initialize(anEdgeMap); it.More(); it.Next()) | |
949 | { | |
950 | BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(it.Key()), aPoly, aT, aLoc); | |
951 | if ( aT.IsNull() || aPoly.IsNull() ) | |
952 | continue; | |
953 | ||
954 | const TColgp_Array1OfPnt& Nodes = aT->Nodes(); | |
955 | const TColStd_Array1OfInteger& Indices = aPoly->Nodes(); | |
956 | const Standard_Integer nbnodes = Indices.Length(); | |
957 | ||
958 | for( Standard_Integer j = 1; j <= nbnodes; j++ ) | |
959 | { | |
960 | gp_Pnt P3d = Nodes(Indices(j)); | |
961 | if( !aLoc.IsIdentity() ) | |
962 | P3d.Transform(aLoc.Transformation()); | |
963 | ||
964 | if( anEdgeMap.Extent() > 1 ) | |
91322f44 | 965 | Sprintf(p,"%d_%d",nbEdge,j); |
d51c7072 | 966 | else |
91322f44 | 967 | Sprintf(p,"%d",j); |
d51c7072 O |
968 | DBRep::Set( newname, BRepBuilderAPI_MakeVertex(P3d) ); |
969 | di.AppendElement(newname); | |
970 | } | |
971 | nbEdge++; | |
972 | } | |
973 | } | |
974 | return 0; | |
975 | } | |
7fd59977 | 976 | |
977 | //======================================================================= | |
7693827d | 978 | //function : correctnormals |
979 | //purpose : Corrects normals in shape triangulation nodes (...) | |
980 | //======================================================================= | |
4006ca98 | 981 | static Standard_Integer correctnormals(Draw_Interpretor& theDI, |
982 | Standard_Integer /*theNArg*/, | |
983 | const char** theArgVal) | |
7693827d | 984 | { |
985 | TopoDS_Shape S = DBRep::Get(theArgVal[1]); | |
986 | ||
987 | //Use "correctnormals shape" | |
988 | ||
989 | ||
990 | if(!BRepLib::EnsureNormalConsistency(S)) | |
991 | { | |
992 | theDI << "Normals have not been changed!\n"; | |
993 | } | |
994 | else | |
995 | { | |
996 | theDI << "Some corrections in source shape have been made!\n"; | |
997 | } | |
998 | ||
999 | return 0; | |
1000 | } | |
1001 | ||
1002 | //======================================================================= | |
0d88155b | 1003 | void MeshTest::Commands(Draw_Interpretor& theCommands) |
7fd59977 | 1004 | //======================================================================= |
1005 | { | |
1006 | Draw::Commands(theCommands); | |
1007 | BRepTest::AllCommands(theCommands); | |
1008 | GeometryTest::AllCommands(theCommands); | |
1009 | MeshTest::PluginCommands(theCommands); | |
1010 | const char* g; | |
1011 | ||
1012 | g = "Mesh Commands"; | |
0d88155b | 1013 | |
49cfd13d | 1014 | theCommands.Add("incmesh","Builds triangular mesh for the shape, run w/o args for help",__FILE__, incrementalmesh, g); |
b508cbc5 | 1015 | theCommands.Add("tessellate","Builds triangular mesh for the surface, run w/o args for help",__FILE__, tessellate, g); |
7fd59977 | 1016 | theCommands.Add("MemLeakTest","MemLeakTest",__FILE__, MemLeakTest, g); |
7fd59977 | 1017 | |
1018 | theCommands.Add("tri2d", "tri2d facename",__FILE__, tri2d, g); | |
1019 | theCommands.Add("trinfo","trinfo name, print triangles information on objects",__FILE__,trianglesinfo,g); | |
1020 | theCommands.Add("veriftriangles","veriftriangles name, verif triangles",__FILE__,veriftriangles,g); | |
1021 | theCommands.Add("wavefront","wavefront name",__FILE__, wavefront, g); | |
d51c7072 | 1022 | theCommands.Add("triepoints", "triepoints shape1 [shape2 ...]",__FILE__, triedgepoints, g); |
7fd59977 | 1023 | |
7693827d | 1024 | theCommands.Add("correctnormals", "correctnormals shape",__FILE__, correctnormals, g); |
7fd59977 | 1025 | } |