1 #ifndef FILE_OCCGEOM
2 #define FILE_OCCGEOM
3 
4 /* *************************************************************************/
5 /* File:   occgeom.hpp                                                     */
6 /* Author: Robert Gaisbauer                                                */
7 /* Date:   26. May  03                                                     */
8 /* *************************************************************************/
9 
10 #ifdef OCCGEOMETRY
11 
12 #include <meshing.hpp>
13 
14 #include <Standard_Version.hxx>
15 #include "BRep_Tool.hxx"
16 #include "Geom_Curve.hxx"
17 #include "Geom2d_Curve.hxx"
18 #include "Geom_Surface.hxx"
19 #include "GeomAPI_ProjectPointOnSurf.hxx"
20 #include "GeomAPI_ProjectPointOnCurve.hxx"
21 #include "BRepTools.hxx"
22 #include "TopExp.hxx"
23 #include "BRepBuilderAPI_MakeVertex.hxx"
24 #include "BRepBuilderAPI_MakeShell.hxx"
25 #include "BRepBuilderAPI_MakeSolid.hxx"
26 #include "BRepOffsetAPI_Sewing.hxx"
27 #include "BRepLProp_SLProps.hxx"
28 #include "BRepAdaptor_Surface.hxx"
29 #include "Poly_Triangulation.hxx"
30 #include "Poly_Array1OfTriangle.hxx"
31 #include "TColgp_Array1OfPnt2d.hxx"
32 #include "Poly_Triangle.hxx"
33 #include "GProp_GProps.hxx"
34 #include "BRepGProp.hxx"
35 #include "gp_Pnt.hxx"
36 #include "TopoDS.hxx"
37 #include "TopoDS_Solid.hxx"
38 #include "TopExp_Explorer.hxx"
39 #include "TopTools_ListIteratorOfListOfShape.hxx"
40 #include "TopoDS_Wire.hxx"
41 #include "BRepTools_WireExplorer.hxx"
42 #include "TopTools_IndexedMapOfShape.hxx"
43 #include "BRepLProp_CLProps.hxx"
44 #include "BRepAdaptor_Curve.hxx"
45 #include "TopoDS_Shape.hxx"
46 #include "TopoDS_Face.hxx"
47 #include "IGESToBRep_Reader.hxx"
48 #include "Interface_Static.hxx"
49 #include "GeomAPI_ExtremaCurveCurve.hxx"
50 #include "Standard_ErrorHandler.hxx"
51 #include "Standard_Failure.hxx"
52 #include "ShapeUpgrade_ShellSewing.hxx"
53 #include "ShapeFix_Shape.hxx"
54 #include "ShapeFix_Wireframe.hxx"
55 #include "BRepMesh_IncrementalMesh.hxx"
56 #include "BRepBndLib.hxx"
57 #include "Bnd_Box.hxx"
58 #include "ShapeAnalysis.hxx"
59 #include "ShapeBuild_ReShape.hxx"
60 #include "BOPAlgo_Builder.hxx"
61 
62 // Philippose - 29/01/2009
63 // OpenCascade XDE Support
64 // Include support for OpenCascade XDE Features
65 #include "TDocStd_Document.hxx"
66 #include "Quantity_Color.hxx"
67 #include "XCAFApp_Application.hxx"
68 #include "XCAFDoc_ShapeTool.hxx"
69 #include "XCAFDoc_Color.hxx"
70 #include "XCAFDoc_ColorTool.hxx"
71 #include "XCAFDoc_ColorType.hxx"
72 #include "XCAFDoc_LayerTool.hxx"
73 #include "XCAFDoc_DimTolTool.hxx"
74 #include "XCAFDoc_MaterialTool.hxx"
75 #include "XCAFDoc_DocumentTool.hxx"
76 #include "TDF_Label.hxx"
77 #include "TDF_LabelSequence.hxx"
78 #include "STEPCAFControl_Reader.hxx"
79 #include "STEPCAFControl_Writer.hxx"
80 #include "IGESCAFControl_Reader.hxx"
81 #include "IGESCAFControl_Writer.hxx"
82 
83 #include "IGESControl_Reader.hxx"
84 #include "STEPControl_Reader.hxx"
85 #include "IGESControl_Writer.hxx"
86 #include "STEPControl_Writer.hxx"
87 
88 #include "StlAPI_Writer.hxx"
89 #include "STEPControl_StepModelType.hxx"
90 
91 #if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=4
92 #define OCC_HAVE_HISTORY
93 #endif
94 
95 
96 
97 
98 namespace netgen
99 {
100 #include "occmeshsurf.hpp"
101 
102   // extern DLL_HEADER MeshingParameters mparam;
103 
104 #define PROJECTION_TOLERANCE 1e-10
105 
106 #define ENTITYISVISIBLE 1
107 #define ENTITYISHIGHLIGHTED 2
108 #define ENTITYISDRAWABLE 4
109 
110 #define OCCGEOMETRYVISUALIZATIONNOCHANGE   0
111 #define OCCGEOMETRYVISUALIZATIONFULLCHANGE 1  // Compute transformation matrices and redraw
112 #define OCCGEOMETRYVISUALIZATIONHALFCHANGE 2  // Redraw
113 
114 
occ2ng(const gp_Pnt & p)115   inline Point<3> occ2ng (const gp_Pnt & p)
116   {
117     return Point<3> (p.X(), p.Y(), p.Z());
118   }
119 
occ2ng(const gp_Pnt2d & p)120   inline Point<2> occ2ng (const gp_Pnt2d & p)
121   {
122     return Point<2> (p.X(), p.Y());
123   }
124 
occ2ng(const gp_Vec & v)125   inline Vec<3> occ2ng (const gp_Vec & v)
126   {
127     return Vec<3> (v.X(), v.Y(), v.Z());
128   }
129 
ng2occ(const Point<3> & p)130   inline gp_Pnt ng2occ (const Point<3> & p)
131   {
132     return gp_Pnt(p(0), p(1), p(2));
133   }
134 
135 
136 
137   class EntityVisualizationCode
138   {
139     int code;
140 
141   public:
142 
EntityVisualizationCode()143     EntityVisualizationCode()
144     {  code = ENTITYISVISIBLE + !ENTITYISHIGHLIGHTED + ENTITYISDRAWABLE;}
145 
IsVisible()146     int IsVisible ()
147     {  return code & ENTITYISVISIBLE;}
148 
IsHighlighted()149     int IsHighlighted ()
150     {  return code & ENTITYISHIGHLIGHTED;}
151 
IsDrawable()152     int IsDrawable ()
153     {  return code & ENTITYISDRAWABLE;}
154 
Show()155     void Show ()
156     {  code |= ENTITYISVISIBLE;}
157 
Hide()158     void Hide ()
159     {  code &= ~ENTITYISVISIBLE;}
160 
Highlight()161     void Highlight ()
162     {  code |= ENTITYISHIGHLIGHTED;}
163 
Lowlight()164     void Lowlight ()
165     {  code &= ~ENTITYISHIGHLIGHTED;}
166 
SetDrawable()167     void SetDrawable ()
168     {  code |= ENTITYISDRAWABLE;}
169 
SetNotDrawable()170     void SetNotDrawable ()
171     {  code &= ~ENTITYISDRAWABLE;}
172   };
173 
174 
175 
176   class Line
177   {
178   public:
179     Point<3> p0, p1;
180     double Dist (Line l);
Length()181     double Length () { return (p1-p0).Length(); }
182   };
183 
184 
185 
Det3(double a00,double a01,double a02,double a10,double a11,double a12,double a20,double a21,double a22)186   inline double Det3 (double a00, double a01, double a02,
187                       double a10, double a11, double a12,
188                       double a20, double a21, double a22)
189   {
190     return a00*a11*a22 + a01*a12*a20 + a10*a21*a02 - a20*a11*a02 - a10*a01*a22 - a21*a12*a00;
191   }
192 
193   class DLL_HEADER OCCParameters
194   {
195   public:
196 
197     /// Factor for meshing close edges, moved to meshingparameters
198     // double resthcloseedgefac = 2.;
199 
200     /// Enable / Disable detection of close edges
201     // int resthcloseedgeenable = true;
202 
203     /// Minimum edge length to be used for dividing edges to mesh points
204     double resthminedgelen = 0.001;
205 
206     /// Enable / Disable use of the minimum edge length (by default use 1e-4)
207     int resthminedgelenenable = true;
208 
209     /*!
210       Dump all the OpenCascade specific meshing parameters
211       to console
212     */
213     void Print (ostream & ost) const;
214   };
215 
216 
217   class ShapeProperties
218   {
219   public:
220     optional<string> name;
221     optional<Vec<3>> col;
222     double maxh = 1e99;
Merge(const ShapeProperties & prop2)223     void Merge(const ShapeProperties & prop2)
224     {
225       if (prop2.name) name = prop2.name;
226       if (prop2.col) col = prop2.col;
227       maxh = min2(maxh, prop2.maxh);
228     }
229   };
230 
231   class OCCIdentification
232   {
233   public:
234     TopoDS_Shape other;
235     Transformation<3> trafo;
236     bool inverse;
237     string name;
238   };
239 
240   class DLL_HEADER OCCGeometry : public NetgenGeometry
241   {
242     Point<3> center;
243     OCCParameters occparam;
244   public:
245     static std::map<Handle(TopoDS_TShape), ShapeProperties> global_shape_properties;
246     static std::map<Handle(TopoDS_TShape), std::vector<OCCIdentification>> identifications;
247     // static std::map<Handle(TopoDS_TShape), string> global_shape_names;
248     // static std::map<Handle(TopoDS_TShape), Vec<3>> global_shape_cols;
249 
250     TopoDS_Shape shape;
251     TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap;
252     NgArray<bool> fsingular, esingular, vsingular;
253     Box<3> boundingbox;
254     NgArray<string> fnames, enames, snames;
255     // Philippose - 29/01/2009
256     // OpenCascade XDE Support
257     // XCAF Handle to make the face colours available to the rest of
258     // the system
259     Handle(XCAFDoc_ColorTool) face_colours;
260 
261     mutable int changed;
262     mutable NgArray<int> facemeshstatus;
263 
264     // Philippose - 15/01/2009
265     // Maximum mesh size for a given face
266     // (Used to explicitly define mesh size limits on individual faces)
267     NgArray<double> face_maxh;
268 
269     // Philippose - 14/01/2010
270     // Boolean array to detect whether a face has been explicitly modified
271     // by the user or not
272     NgArray<bool> face_maxh_modified;
273 
274     // Philippose - 15/01/2009
275     // Indicates which faces have been selected by the user in geometry mode
276     // (Currently handles only selection of one face at a time, but an array would
277     //  help to extend this to multiple faces)
278     NgArray<bool> face_sel_status;
279 
280     NgArray<EntityVisualizationCode> fvispar, evispar, vvispar;
281 
282     double tolerance;
283     bool fixsmalledges;
284     bool fixspotstripfaces;
285     bool sewfaces;
286     bool makesolids;
287     bool splitpartitions;
288 
289     int occdim = 3; // meshing is always done 3D, changed to 2D later of occdim=2
290 
OCCGeometry()291     OCCGeometry()
292     {
293       somap.Clear();
294       shmap.Clear();
295       fmap.Clear();
296       wmap.Clear();
297       emap.Clear();
298       vmap.Clear();
299     }
300 
301     OCCGeometry(const TopoDS_Shape& _shape, int aoccdim = 3);
302 
GetGeomType() const303     Mesh::GEOM_TYPE GetGeomType() const override
304     { return Mesh::GEOM_OCC; }
305 
SetOCCParameters(const OCCParameters & par)306     void SetOCCParameters(const OCCParameters& par)
307     { occparam = par; }
308 
309     void Analyse(Mesh& mesh,
310                  const MeshingParameters& mparam) const override;
311     void FindEdges(Mesh& mesh,
312                    const MeshingParameters& mparam) const override;
313     void MeshSurface(Mesh& mesh,
314                      const MeshingParameters& mparam) const override;
315 
316     void FinalizeMesh(Mesh& mesh) const override;
317 
318     void Save (string filename) const override;
319 
320     void DoArchive(Archive& ar) override;
321 
322     PointGeomInfo ProjectPoint(int surfind, Point<3> & p) const override;
323     void ProjectPointEdge (int surfind, int surfind2, Point<3> & p,
324                            EdgePointGeomInfo* gi = nullptr) const override;
325     bool ProjectPointGI (int surfind, Point<3> & p, PointGeomInfo & gi) const override;
326     Vec<3> GetNormal(int surfind, const Point<3> & p, const PointGeomInfo* gi) const override;
327     bool CalcPointGeomInfo(int surfind, PointGeomInfo& gi, const Point<3> & p3) const override;
328 
329     void PointBetweenEdge(const Point<3> & p1, const Point<3> & p2, double secpoint,
330                           int surfi1, int surfi2,
331                           const EdgePointGeomInfo & ap1,
332                           const EdgePointGeomInfo & ap2,
333                           Point<3> & newp, EdgePointGeomInfo & newgi) const override;
334     void PointBetween(const Point<3> & p1, const Point<3> & p2, double secpoint,
335                       int surfi,
336                       const PointGeomInfo & gi1,
337                       const PointGeomInfo & gi2,
338                       Point<3> & newp, PointGeomInfo & newgi) const override;
339 
340     void BuildFMap();
341 
GetShape() const342     auto GetShape() const { return shape; }
GetBoundingBox() const343     Box<3> GetBoundingBox() const
344     { return boundingbox; }
345 
NrSolids() const346     int NrSolids() const
347     { return somap.Extent(); }
348 
349     // Philippose - 17/01/2009
350     // Total number of faces in the geometry
NrFaces() const351     int NrFaces() const
352     { return fmap.Extent(); }
353 
SetCenter()354     void SetCenter()
355     { center = boundingbox.Center(); }
356 
Center() const357     Point<3> Center() const
358     { return center; }
359 
GetSurface(int surfi)360     OCCSurface GetSurface (int surfi)
361     {
362       cout << "OCCGeometry::GetSurface using PLANESPACE" << endl;
363       return OCCSurface (TopoDS::Face(fmap(surfi)), PLANESPACE);
364     }
365 
366     void CalcBoundingBox ();
367     void BuildVisualizationMesh (double deflection);
368 
369     void RecursiveTopologyTree (const TopoDS_Shape & sh,
370                                 stringstream & str,
371                                 TopAbs_ShapeEnum l,
372                                 bool free,
373                                 const char * lname);
374 
375     void GetTopologyTree (stringstream & str);
376 
377     void PrintNrShapes ();
378 
379     void CheckIrregularEntities (stringstream & str);
380 
381     void SewFaces();
382 
383     void MakeSolid();
384 
385     void HealGeometry();
386     void GlueGeometry();
387 
388     // Philippose - 15/01/2009
389     // Sets the maximum mesh size for a given face
390     // (Note: Local mesh size limited by the global max mesh size)
SetFaceMaxH(int facenr,double faceh,const MeshingParameters & mparam)391     void SetFaceMaxH(int facenr, double faceh, const MeshingParameters & mparam)
392     {
393       if((facenr> 0) && (facenr <= fmap.Extent()))
394         {
395           face_maxh[facenr-1] = min(mparam.maxh,faceh);
396 
397           // Philippose - 14/01/2010
398           // If the face maxh is greater than or equal to the
399           // current global maximum, then identify the face as
400           // not explicitly controlled by the user any more
401           if(faceh >= mparam.maxh)
402             {
403               face_maxh_modified[facenr-1] = 0;
404             }
405           else
406             {
407               face_maxh_modified[facenr-1] = 1;
408             }
409         }
410     }
411 
SetFaceMaxH(size_t facenr,double faceh)412     void SetFaceMaxH(size_t facenr, double faceh)
413     {
414       if(facenr >= fmap.Extent())
415         throw RangeException("OCCGeometry faces", facenr, 0, fmap.Extent());
416       face_maxh[facenr] = faceh;
417       face_maxh_modified[facenr] = true;
418     }
419 
420     // Philippose - 15/01/2009
421     // Returns the local mesh size of a given face
GetFaceMaxH(int facenr)422     double GetFaceMaxH(int facenr)
423     {
424       if((facenr> 0) && (facenr <= fmap.Extent()))
425         {
426           return face_maxh[facenr-1];
427         }
428       else
429         {
430           return 0.0;
431         }
432     }
433 
434     // Philippose - 14/01/2010
435     // Returns the flag whether the given face
436     // has a mesh size controlled by the user or not
GetFaceMaxhModified(int facenr)437     bool GetFaceMaxhModified(int facenr)
438     {
439       return face_maxh_modified[facenr-1];
440     }
441 
442     // Philippose - 17/01/2009
443     // Returns the index of the currently selected face
SelectedFace()444     int SelectedFace()
445     {
446       for(int i = 1; i <= fmap.Extent(); i++)
447         {
448           if(face_sel_status[i-1])
449             {
450               return i;
451             }
452         }
453 
454       return 0;
455     }
456 
457     // Philippose - 17/01/2009
458     // Sets the currently selected face
SetSelectedFace(int facenr)459     void SetSelectedFace(int facenr)
460     {
461       face_sel_status = 0;
462 
463       if((facenr >= 1) && (facenr <= fmap.Extent()))
464         {
465           face_sel_status[facenr-1] = 1;
466         }
467     }
468 
LowLightAll()469     void LowLightAll()
470     {
471       for (int i = 1; i <= fmap.Extent(); i++)
472         fvispar[i-1].Lowlight();
473       for (int i = 1; i <= emap.Extent(); i++)
474         evispar[i-1].Lowlight();
475       for (int i = 1; i <= vmap.Extent(); i++)
476         vvispar[i-1].Lowlight();
477     }
478 
479     void GetUnmeshedFaceInfo (stringstream & str);
480     void GetNotDrawableFaces (stringstream & str);
481     bool ErrorInSurfaceMeshing ();
482 
483     //      void WriteOCC_STL(char * filename);
484 
485   private:
486     bool FastProject (int surfi, Point<3> & ap, double& u, double& v) const;
487   };
488 
489 
490   void PrintContents (OCCGeometry * geom);
491 
492   DLL_HEADER OCCGeometry * LoadOCC_IGES (const char * filename);
493   DLL_HEADER OCCGeometry * LoadOCC_STEP (const char * filename);
494   DLL_HEADER OCCGeometry * LoadOCC_BREP (const char * filename);
495 
496   // Philippose - 31.09.2009
497   // External access to the mesh generation functions within the OCC
498   // subsystem (Not sure if this is the best way to implement this....!!)
499   DLL_HEADER extern void OCCSetLocalMeshSize(const OCCGeometry & geom, Mesh & mesh, const MeshingParameters & mparam,
500                                              const OCCParameters& occparam);
501 
502   DLL_HEADER extern void OCCMeshSurface (const OCCGeometry & geom, Mesh & mesh, const MeshingParameters & mparam);
503 
504   DLL_HEADER extern void OCCOptimizeSurface (OCCGeometry & geom, Mesh & mesh, const MeshingParameters & mparam);
505 
506   DLL_HEADER extern void OCCFindEdges (const OCCGeometry & geom, Mesh & mesh, const MeshingParameters & mparam);
507 }
508 
509 #endif
510 
511 #endif
512