WaveBEM: Unsteady Nonlinear Potential Flow Solver for Ship-Wave Interaction.
occ_utilities.cc
Go to the documentation of this file.
1 #include "occ_utilities.h"
2 
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <iostream>
7 #include <set>
8 #include <IGESControl_Reader.hxx>
9 #include <IGESControl_Controller.hxx>
10 #include <IGESControl_Writer.hxx>
11 #include <TopoDS.hxx>
12 #include <TopoDS_Shape.hxx>
13 #include <TopoDS_Shell.hxx>
14 #include <TopoDS_Face.hxx>
15 #include <TopoDS_Edge.hxx>
16 #include <BRepTools.hxx>
17 #include <XSControl_Reader.hxx>
18 #include <TopTools_SequenceOfShape.hxx>
19 #include <Handle_Standard_Transient.hxx>
20 #include <TColStd_SequenceOfTransient.hxx>
21 #include <TColStd_HSequenceOfTransient.hxx>
22 #include <TopExp_Explorer.hxx>
23 #include <gp_Pnt.hxx>
24 #include <gp_Vec.hxx>
25 #include <GeomAPI_ProjectPointOnSurf.hxx>
26 #include <GeomAPI_ProjectPointOnCurve.hxx>
27 #include <Standard_Real.hxx>
28 #include <Standard_Integer.hxx>
29 #include <BRep_Tool.hxx>
30 #include <Geom_Surface.hxx>
31 #include <Geom_Plane.hxx>
32 #include <Prs3d_ShapeTool.hxx>
33 #include <GeomAPI_IntSS.hxx>
34 #include <Bnd_Box.hxx>
35 #include <gp_Trsf.hxx>
36 #include <gp_Ax3.hxx>
37 #include <gp_Pln.hxx>
38 #include <BRepBuilderAPI_Transform.hxx>
39 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
40 #include <BRepBuilderAPI_MakeEdge.hxx>
41 #include <TColGeom_Array1OfCurve.hxx>
42 #include <TColgp_HArray1OfPnt.hxx>
43 #include <Geom_Curve.hxx>
44 #include <Geom_BoundedCurve.hxx>
45 #include <Geom_TrimmedCurve.hxx>
46 #include <Geom_BSplineCurve.hxx>
47 #include <GeomAPI_Interpolate.hxx>
48 #include <BRepAlgo_Section.hxx>
49 #include <boost/bind.hpp>
50 #include <GeomLib_Tool.hxx>
51 #include <TColGeom_Array2OfBezierSurface.hxx>
52 #include <ProjLib_ProjectOnPlane.hxx>
53 #include <Adaptor3d_HCurve.hxx>
54 #include <GeomAdaptor_HCurve.hxx>
55 #include <ShapeAnalysis_Surface.hxx>
56 #include <GeomLProp_SLProps.hxx>
57 #include <BRepExtrema_DistShapeShape.hxx>
58 #include <BRepBuilderAPI_MakeVertex.hxx>
59 #include <GCPnts_AbscissaPoint.hxx>
60 #include <GeomLProp_CLProps.hxx>
61 #include <BRep_Builder.hxx>
62 #include <Bnd_Box.hxx>
63 #include <BRepBndLib.hxx>
64 #include <BRepMesh.hxx>
65 #include <GeomPlate_BuildPlateSurface.hxx>
66 #include <GeomPlate_MakeApprox.hxx>
67 #include <GeomAdaptor_HCurve.hxx>
68 #include <Adaptor3d_HCurveOnSurface.hxx>
69 #include <GeomPlate_CurveConstraint.hxx>
70 #include <TColgp_SequenceOfXY.hxx>
71 #include <TColgp_SequenceOfXYZ.hxx>
72 #include <GeomPlate_PlateG0Criterion.hxx>
73 #include <BRepBuilderAPI_MakeWire.hxx>
74 #include <BRepBuilderAPI_MakeFace.hxx>
75 #include <BRepMesh_IncrementalMesh.hxx>
76 #include <Poly_Triangulation.hxx>
77 #include <BRepMesh_FastDiscret.hxx>
78 
79 #define FALSE 0
80 #define TRUE 1
81 
82 #include <deal.II/base/utilities.h>
84 #include <vector>
85 #include <algorithm>
86 
87 using namespace dealii;
88 using namespace std;
89 using namespace numbers;
90 
91 namespace OpenCascade
92 {
93 
94  TopoDS_Shape read_IGES(string filename, double scale_factor)
95  {
96  IGESControl_Reader reader;
97  IFSelect_ReturnStatus stat;
98  stat = reader.ReadFile(filename.c_str());
99  Standard_Boolean failsonly = Standard_False;
100  IFSelect_PrintCount mode = IFSelect_ItemsByEntity;
101  reader.PrintCheckLoad (failsonly, mode);
102  Standard_Integer nIgesFaces,nTransFaces;
103 
104  Handle(TColStd_HSequenceOfTransient) myList = reader.GiveList("iges-faces");
105  //selects all IGES faces in the
106  //file and puts them into a list
107  //called MyList,
108  nIgesFaces = myList->Length();
109  nTransFaces = reader.TransferList(myList);
110 
111  AssertThrow(nTransFaces > 0, ExcMessage("Read nothing from file."));
112 
113  // Handle IGES Scale here.
114  gp_Pnt Origin;
115  gp_Trsf scale;
116  scale.SetScale (Origin, scale_factor);
117 
118  TopoDS_Shape sh = reader.OneShape();
119  BRepBuilderAPI_Transform trans(sh, scale);
120 
121  return trans.Shape(); // this is the actual translation
122  }
123 
124  TopoDS_Shape extract_xz_edges(const TopoDS_Shape &in_shape,
125  const double tolerance,
126  const unsigned int max_num_edges)
127  {
128 
130  TopExp_Explorer edgeExplorer(in_shape , TopAbs_EDGE);
131  unsigned int numKeelEdges = 0;
132  unsigned int numEdges = 0;
133 
134  TopoDS_Edge edge = TopoDS::Edge(edgeExplorer.Current());
135  TopLoc_Location L;
136  Standard_Real First;
137  Standard_Real Last;
138  gp_Pnt PIn(0.0,0.0,0.0);
139  gp_Pnt PFin(0.0,0.0,0.0);
140  gp_Pnt PMid(0.0,0.0,0.0);
141 
142  Handle(Geom_Curve) curveOne = BRep_Tool::Curve(edge,L,First,Last);
143  std::vector< Handle(Geom_Curve) > please;
144 
145  while (edgeExplorer.More())
146  {
147  edge = TopoDS::Edge(edgeExplorer.Current());
148  if (BRep_Tool::Degenerated(edge))
149  {
150  }
151  else
152  {
153  Handle(Geom_Curve) curve = BRep_Tool::Curve(edge,L,First,Last);
154  curve->D0(First,PIn);
155  curve->D0(Last,PFin);
156  curve->D0((First+Last)/2.0,PMid);
157  //cout<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<" ---> ";
158  //cout<<fabs(double(PIn.Y())+double(PFin.Y())+double(PMid.Y()))/3.0<<endl;
159  if ((fabs(double(PIn.Y())+double(PFin.Y())+double(PMid.Y()))/3.0 < tolerance) &&
160  (PIn.Distance(PMid)+PFin.Distance(PMid) > tolerance) )
161  {
162  cout<<numKeelEdges<<": "<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<endl;
163  please.push_back(curve);
164  ++numKeelEdges;
165  }
166  }
167  ++numEdges;
168  edgeExplorer.Next();
169  }
170 
171  numKeelEdges = please.size();
172  cout<<"numKeelEdges "<<numKeelEdges<<endl;
173  AssertThrow(numKeelEdges>0,
174  ExcMessage("No edges on xz plane"));
175 
176  for (unsigned int i=0; i<numKeelEdges; ++i)
177  {
178  Handle(Geom_Curve) curvez = please[i];
179  First = curvez->FirstParameter();
180  Last = curvez->LastParameter();
181  curvez->D0(First,PIn);
182  curvez->D0(Last,PFin);
183  curvez->D0((First+Last)/2.0,PMid);
184  cout<<i<<": "<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<endl;
185  }
186 //*/
187  Handle(Geom_Curve) curve1 = please[0];
188  Handle(Geom_BoundedCurve) bcurve1 = Handle(Geom_BoundedCurve)::DownCast(curve1);
189  GeomConvert_CompCurveToBSplineCurve convert_keel_bspline(bcurve1,Convert_TgtThetaOver2);
190  bool check = false, one_added = true, one_failed=true;
191  vector<bool> added(numKeelEdges, false);
192  added[0] = true;
193  unsigned int added_count = 1;
194  while (one_added == true)
195  {
196 
197  one_added = false;
198  one_failed = false;
199  for (unsigned int i=1; i<numKeelEdges; ++i)
200  if (added[i] == false)
201  {
202  cout<<"Curve "<<i<<" of "<<numKeelEdges<<" ("<<added_count<<" already added"<<")"<<endl;
203  Handle(Geom_Curve) curve = please[i];
204  First = curve->FirstParameter();
205  Last = curve->LastParameter();
206  curve->D0(First,PIn);
207  curve->D0(Last,PFin);
208  curve->D0((First+Last)/2.0,PMid);
209  cout<<"To be added "<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<endl;
210  Handle(Geom_Curve) temp = convert_keel_bspline.BSplineCurve();
211  First = temp->FirstParameter();
212  Last = temp->LastParameter();
213  temp->D0(First,PIn);
214  temp->D0(Last,PFin);
215  temp->D0((First+Last)/2.0,PMid);
216  cout<<"Keel "<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<endl;
217  Handle(Geom_BoundedCurve) bcurve = Handle(Geom_BoundedCurve)::DownCast(curve);
218  check = convert_keel_bspline.Add(bcurve,tolerance,0,1,0);
219  one_failed = one_failed || (check == false);
220  one_added = one_added || (check == true);
221  added[i] = check;
222  if (added[i] == true)
223  {
224  added_count++;
225  cout<<"One Added!"<<endl;
226  }
227  }
228  }
229 
230  AssertThrow(one_failed == false,
231  ExcMessage("Bspline conversion has failed."));
232 
233 
234  Handle(Geom_BSplineCurve) equiv_keel_bspline = convert_keel_bspline.BSplineCurve();
235 
236  Handle(Geom_Curve) bspline = convert_keel_bspline.BSplineCurve();
237 
238  GeomAdaptor_Curve AC = GeomAdaptor_Curve(bspline);
239  Handle(GeomAdaptor_HCurve) ACH = new GeomAdaptor_HCurve(AC);
240  gp_Ax3 Ax(gp_Pnt(0.0,0.0,0.0),gp_Dir(0.0,1.0,0.0),gp_Dir(1.0,0.0,0.0));
241  ProjLib_ProjectOnPlane projOnPlane(Ax);
242 
243  projOnPlane.Load(ACH, 1e-7, Standard_True);
244 
245  Handle(Geom_BSplineCurve) equiv_keel_bspline_xy = projOnPlane.BSpline();
246 
247  Handle(Geom_Curve) bspline_xy = projOnPlane.BSpline();
248 
249  if (bspline_xy->IsCN(1))
250  cout<<"XY edges curve is at least C1"<<endl;
251  else
252  cout<<"XY edges curve is not C1"<<endl;
253 
254  TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(bspline_xy);
255  new_edge.Location(L);
256 
257 
258  return new_edge;
259  }
260 
261 
262  TopoDS_Shape extract_transom_edges(const TopoDS_Shape &in_shape,
263  const unsigned int num_transom_edges,
264  const double tolerance)
265  {
266  cout<<"Requested transom edges: "<<num_transom_edges<<endl;
268  TopExp_Explorer edgeExplorer(in_shape , TopAbs_EDGE);
269  unsigned int numEdges = 0;
270 
271  TopoDS_Edge edge;
272  TopLoc_Location L;
273  Standard_Real First;
274  Standard_Real Last;
275  gp_Pnt PIn(0.0,0.0,0.0);
276  gp_Pnt PFin(0.0,0.0,0.0);
277  gp_Pnt PMid(0.0,0.0,0.0);
278  TColGeom_Array1OfCurve curve_array(0,num_transom_edges);
279  std::multiset< pair<unsigned int,double> , edge_ordering_rule > edges_set;
280  typedef std::multiset< std::pair<unsigned int,double>, edge_ordering_rule >::iterator iterator;
281 
282 
283  while (edgeExplorer.More())
284  {
285  edge = TopoDS::Edge(edgeExplorer.Current());
286  if (BRep_Tool::Degenerated(edge))
287  {
288  }
289  else
290  {
291  Handle(Geom_Curve) curve = BRep_Tool::Curve(edge,L,First,Last);
292  curve->D0((First+Last)/2.0,PMid);
293  //cout<<"** "<<numEdges<<" "<<Pnt(PMid)<<endl;
294  edges_set.insert(std::pair<unsigned int, double >(numEdges, PMid.X()));
295  }
296  ++numEdges;
297  edgeExplorer.Next();
298  }
299 
300  //for (iterator pos=edges_set.begin(); pos!=edges_set.end();++pos)
301  // cout<<"*** "<<pos->first<<" "<<pos->second<<endl;
302 
303 
304  iterator it = edges_set.end();
305  for (unsigned int i=0; i<num_transom_edges; ++i)
306  {
307  it--;
308  numEdges = 0;
309  edgeExplorer.ReInit();
310  while (edgeExplorer.More())
311  {
312  edge = TopoDS::Edge(edgeExplorer.Current());
313  if (BRep_Tool::Degenerated(edge))
314  {
315  }
316  else
317  {
318  Handle(Geom_Curve) curve = BRep_Tool::Curve(edge,L,First,Last);
319  if (numEdges == it->first)
320  {
321  curve->D0((First+Last)/2.0,PMid);
322  //cout<<"* "<<i<<" "<<Pnt(PMid)<<endl;
323  curve_array(i) = curve;
324  }
325  }
326  ++numEdges;
327  edgeExplorer.Next();
328  }
329  }
330 
331 
332  Handle(Geom_Curve) curve1 = curve_array(0);
333  Handle(Geom_BoundedCurve) bcurve1 = Handle(Geom_BoundedCurve)::DownCast(curve1);
334  GeomConvert_CompCurveToBSplineCurve convert_transom_bspline(bcurve1,Convert_TgtThetaOver2);
335  bool check = false, one_added = true, one_failed=true;
336  vector<bool> added(num_transom_edges, false);
337  added[0] = true;
338  while (one_added == true)
339  {
340  one_added = false;
341  one_failed = false;
342  for (unsigned int i=1; i<num_transom_edges; ++i)
343  {
344  if (added[i] == false)
345  {
346  Handle(Geom_Curve) curve = curve_array(i);
347  Handle(Geom_BoundedCurve) bcurve = Handle(Geom_BoundedCurve)::DownCast(curve);
348  check = convert_transom_bspline.Add(bcurve,tolerance,0,1,0);
349  one_failed = one_failed || (check == false);
350  one_added = one_added || (check == true);
351  added[i] = check;
352  }
353  }
354  }
355 
356  AssertThrow(one_failed == false,
357  ExcMessage("Bspline conversion of transom edges has failed."));
358 
359 
360  Handle(Geom_BSplineCurve) equiv_transom_bspline = convert_transom_bspline.BSplineCurve();
361 
362  Handle(Geom_Curve) bspline = convert_transom_bspline.BSplineCurve();
363 
364 
365  if (bspline->IsCN(1))
366  cout<<"Transom curve is at least C1"<<endl;
367  else
368  cout<<"Transom curve is not C1"<<endl;
369 
370 
371  TopoDS_Edge new_transom_edge = BRepBuilderAPI_MakeEdge(bspline);
372  new_transom_edge.Location(L);
373 
374 // These lines can be used to dump the keel bslpine on an .igs file
375  /*
376  IGESControl_Controller::Init();
377  IGESControl_Writer ICW ("MM", 0);
378  Standard_Boolean ok = ICW.AddShape (new_transom_edge);
379  ICW.ComputeModel();
380  Standard_Boolean OK = ICW.Write ("MyTransom.igs");
381  */
382 
383 
384  return new_transom_edge;
385 
386 
387 
388  }
389 
390  TopoDS_Shape merge_surfaces(const TopoDS_Shape &/*in_shape*/,
391  const double /*tolerance*/)
392  {
393 
394  TopoDS_Shape shape;
395  /*
396  TopExp_Explorer faceExplorer(sh, TopAbs_FACE);
397  TopoDS_Face face;
398  unsigned int face_count = 0;
399  while(faceExplorer.More())
400  {
401  face = TopoDS::Face(faceExplorer.Current());
402  //Standard_Real umin, umax, vmin, vmax;
403  //BRepTools::UVBounds(face, umin, umax, vmin, vmax); // create surface
404  //Handle(Geom_Surface) surf=BRep_Tool::Surface(face); // get surface properties
405  faceExplorer.Next();
406  ++face_count;
407  }
408 
409  TColGeom_Array2OfBezierSurface surface_array(0, face_count, 0, 0);
410  faceExplorer.Reinit();
411  face_count = 0;
412  while(faceExplorer.More())
413  {
414  face = TopoDS::Face(faceExplorer.Current());
415  //Standard_Real umin, umax, vmin, vmax;
416  //BRepTools::UVBounds(face, umin, umax, vmin, vmax);
417  Handle(Geom_Surface) surf=BRep_Tool::Surface(face); // create surface
418  surface_array.SetValue(face_count,0,surf);
419  faceExplorer.Next();
420  ++face_count;
421  }
422 
423  AssertThrow(numKeelEdges>0,
424  ExcMessage("No edges on xz plane"));
425 
426  Handle(Geom_Curve) curve1 = curve_array(0);
427  Handle(Geom_BoundedCurve) bcurve1 = Handle(Geom_BoundedCurve)::DownCast(curve1);
428  GeomConvert_CompCurveToBSplineCurve convert_keel_bspline(bcurve1,Convert_TgtThetaOver2);
429  bool check = false, one_added = true, one_failed=true;
430  vector<bool> added(numKeelEdges, false);
431  added[0] = true;
432  while(one_added == true)
433  {
434  one_added = false;
435  one_failed = false;
436  for (unsigned int i=1; i<numKeelEdges; ++i)
437  if(added[i] == false)
438  {
439  Handle(Geom_Curve) curve = curve_array(i);
440  Handle(Geom_BoundedCurve) bcurve = Handle(Geom_BoundedCurve)::DownCast(curve);
441  check = convert_keel_bspline.Add(bcurve,1e-5,0,1,0);
442  one_failed = one_failed || (check == false);
443  one_added = one_added || (check == true);
444  added[i] = check;
445  }
446  }
447 
448  AssertThrow(one_failed == false,
449  ExcMessage("Bspline convertion has failed."));
450 
451 
452  Handle(Geom_BSplineCurve) equiv_keel_bspline = convert_keel_bspline.BSplineCurve();
453 
454  Handle(Geom_Curve) bspline = convert_keel_bspline.BSplineCurve();
455  return BRepBuilderAPI_MakeEdge(bspline);
456  */
457  return shape;
458 
459  }
460 
461  void intersect_plane(const TopoDS_Shape &in_shape,
462  TopoDS_Shape &out_shape,
463  const double c_x,
464  const double c_y,
465  const double c_z,
466  const double c,
467  const double tolerance)
468  {
469  Handle(Geom_Plane) plane = new Geom_Plane(c_x,c_y,c_z,c);
470 
471  // This is to loop on the faces,
472  // that extracts all
473  // intersections.
474 
475  //TopExp_Explorer faceExplorer(in_shape , TopAbs_FACE);
476 
477  std::vector<Handle_Geom_BoundedCurve> intersections;
478 
479  BRepAlgo_Section section(in_shape, plane);
480  TopoDS_Shape edges = section.Shape();
481 
482  TopoDS_Edge edge;
483  TopLoc_Location L;
484  Standard_Real First;
485  Standard_Real Last;
486  gp_Pnt PIn(0.0,0.0,0.0);
487  gp_Pnt PFin(0.0,0.0,0.0);
488  gp_Pnt PMid(0.0,0.0,0.0);
489  TopExp_Explorer edgeExplorer(edges , TopAbs_EDGE);
490  unsigned int count = 0;
491  while (edgeExplorer.More())
492  {
493  edge = TopoDS::Edge(edgeExplorer.Current());
494  Handle(Geom_Curve) curve = BRep_Tool::Curve(edge,L,First,Last);
495  intersections.push_back(Handle(Geom_BoundedCurve)::DownCast(curve));
496 
497  curve->D0(First,PIn);
498  curve->D0(Last,PFin);
499  curve->D0((First+Last)/2.0,PMid);
500  //cout<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<" ---> ";
501  //cout<<fabs(double(PIn.Y())+double(PFin.Y())+double(PMid.Y()))/3.0<<endl;
502 
503  cout<<count<<": "<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<endl;
504 
505  //IGESControl_Controller::Init();
506  //IGESControl_Writer ICW ("MM", 0);
507  //Standard_Boolean ok = ICW.AddShape (edge);
508  //ICW.ComputeModel();
509  //Standard_Boolean OK = ICW.Write ("water_line.igs");
510  //count++;
511 
512  edgeExplorer.Next();
513 
514  }
515 
516  // Now we build a single bspline
517  // out of all the geometrical
518  // curves
519  unsigned int numIntersEdges = intersections.size();
520  for (unsigned int i = 0; i<intersections.size(); ++i)
521  {
522  if (intersections[i]->Value(intersections[i]->FirstParameter()).X() >
523  intersections[i]->Value(intersections[i]->LastParameter()).X() )
524  intersections[i]->Reverse();
525  }
526 
527  GeomConvert_CompCurveToBSplineCurve
528  convert_bspline(intersections[0], Convert_TgtThetaOver2);
529  bool check = false, one_added = true, one_failed=true;
530  vector<bool> added(numIntersEdges, false);
531  added[0] = true;
532  while (one_added == true)
533  {
534  one_added = false;
535  one_failed = false;
536  for (unsigned int i=1; i<numIntersEdges; ++i)
537  if (added[i] == false)
538  {
539  Handle(Geom_Curve) curve = intersections[i];
540  Handle(Geom_BoundedCurve) bcurve = Handle(Geom_BoundedCurve)::DownCast(curve);
541  check = convert_bspline.Add(bcurve,tolerance,0,1,0);
542  one_failed = one_failed || (check == false);
543  one_added = one_added || (check == true);
544  added[i] = check;
545  //cout<<i<<" --> "<<added[i]<<" "<<false<<endl;
546  }
547  }
548 
549  AssertThrow(one_failed == false,
550  ExcMessage("Bspline convertion of intersection with plane has failed."));
551 
552  Handle(Geom_Curve) bspline = convert_bspline.BSplineCurve();
553 
554  out_shape = BRepBuilderAPI_MakeEdge(bspline);
555 
556  if (bspline->IsCN(1))
557  cout<<"Intersection with plane is at least a C1 curve"<<endl;
558  else
559  cout<<"Intersection with plane is not a C1 curve "<<endl;
560 
561 
562  }
563 
564 
565 
566  Handle_Geom_Curve interpolation_curve_points_sort(std::vector<Point<3> > &curve_points,
567  Point<3> direction)
568  {
569 
570  unsigned int n_vertices = curve_points.size();
571 
572  if (direction*direction > 0)
573  {
574  std::sort(curve_points.begin(), curve_points.end(),
575  boost::bind(&point_compare, _1, _2, direction));
576  }
577 
578  // set up array of vertices
579  Handle(TColgp_HArray1OfPnt) vertices = new TColgp_HArray1OfPnt(1,n_vertices);
580  for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
581  {
582  vertices->SetValue(vertex+1,OpenCascade::Pnt(curve_points[vertex]));
583  }
584 
585 
586  GeomAPI_Interpolate bspline_generator(vertices, Standard_False, 1.0e-7);
587  bspline_generator.Perform();
588  AssertThrow( (bspline_generator.IsDone()), ExcMessage("Interpolated bspline generation failed"));
589  //Handle(Geom_BSplineCurve) bspline = new Geom_BSplineCurve(*(bspline_generator.Curve().operator->()));
590  Handle(Geom_BSplineCurve) bspline = bspline_generator.Curve();
591 
592  return bspline;
593  }
594 
595 
596  Handle_Geom_Curve interpolation_curve(std::vector<Point<3> > &curve_points)
597  {
598 
599  unsigned int n_vertices = curve_points.size();
600 
601  // set up array of vertices
602  Handle(TColgp_HArray1OfPnt) vertices = new TColgp_HArray1OfPnt(1,n_vertices);
603  for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
604  {
605  vertices->SetValue(vertex+1,OpenCascade::Pnt(curve_points[vertex]));
606  }
607 
608 
609  GeomAPI_Interpolate bspline_generator(vertices, Standard_False, 1.0e-7);
610  bspline_generator.Perform();
611 
612  //Handle(Geom_Curve) bspline = new Geom_BSplineCurve(*(bspline_generator.Curve().operator->()));
613 
614  Handle(Geom_BSplineCurve) bspline = bspline_generator.Curve();
615  return bspline;
616  }
617 
618 
619 
621  {
622  //TopoDS_Shape sh = read_IGES("/home/amola/workspace/FRANCO_TETGEN/tower_bridge_cf_IGES.igs",0.001);
623  //TopoDS_Shape sh = read_IGES("/home/amola/workspace/FRANCO_TETGEN/VIOLA_BRIDGE/viola-bridge-1/viola_bridge.iges",0.0254);
624  TopoDS_Shape sh = read_IGES("/home/amola/workspace/openship/trunk/WaveBEM/utilities/kcs.iges",0.001);
625  //TopoDS_Shape sh = read_IGES("/home/amola/workspace/openship/trunk/WaveBEM/utilities/goteborg.iges",0.001);
626  //TopoDS_Shape sh = read_IGES("/home/amola/workspace/FRANCO_TETGEN/cognit.iges",0.001);
627  //TopoDS_Shape sh = read_IGES("/home/amola/workspace/FRANCO_TETGEN/COFANO/cofanoSpostatoTanto.igs",0.001);
628  //TopoDS_Shape sh = read_IGES("/home/amola/workspace/FRANCO_TETGEN/CANOTTAGGIO/doppio_placido.iges",0.001);
629  //TopoDS_Shape sh = read_IGES("/home/amola/workspace/openship/trunk/WaveBEM/utilities/fc_ship.iges",0.001);
630  //TopoDS_Shape sh = read_IGES("/home/amola/workspace/FRANCO_TETGEN/ESEMPIO_HANG/22imr_retro.igs",0.001);
631 
632  using dealii::numbers::PI;
633  Standard_Real AngTol = 10.0/180.0;
634  Standard_Real LinTol = 2e-3;
635 
636  std::vector<TopoDS_Edge> feature_edges;
637 
638  TopExp_Explorer faceExplorer(sh, TopAbs_FACE);
639  TopoDS_Face face;
640  unsigned int face_count = 0;
641  std::vector<Bnd_Box> facesBndBoxes;
642 
643  while (faceExplorer.More())
644  {
645  face = TopoDS::Face(faceExplorer.Current());
646  //BRepMesh::Mesh(face, 0.01f);
647  Bnd_Box bndBox;
648  BRepBndLib::Add(face, bndBox);
649  bndBox.Enlarge(100*LinTol);
650  facesBndBoxes.push_back(bndBox);
651  ++face_count;
652  faceExplorer.Next();
653  }
654 
655  unsigned int num_faces = face_count;
656  std::vector< std::set<unsigned int> > faces_neighbors_sets(num_faces);
657 
658  face_count = 0;
659  faceExplorer.Init(sh, TopAbs_FACE);
660 
661  while (faceExplorer.More())
662  {
663  face = TopoDS::Face(faceExplorer.Current());
664  Handle(Geom_Surface) ssurface = BRep_Tool::Surface(face);
665  double u1,u2,v1,v2;
666  ssurface->Bounds(u1,u2,v1,v2);
667  cout<<"Face "<<face_count<<" Center ("<<Pnt(ssurface->Value((u1+u2)/2.0,(v1+v2)/2.0))<<")"<<endl;
668  faces_neighbors_sets[face_count].insert(face_count);
669  TopExp_Explorer edgeExplorer(face, TopAbs_EDGE);
670  TopoDS_Edge edge;
671  gp_Pnt PMid;
672  gp_Vec TangMid;
673  unsigned int edge_count = 0;
674  while (edgeExplorer.More())
675  {
676  edge = TopoDS::Edge(edgeExplorer.Current());
677  if (BRep_Tool::Degenerated(edge))
678  {
679  }
680  else
681  {
682  TopLoc_Location L;
683  Standard_Real First;
684  Standard_Real Last;
685  Handle(Geom_Curve) curve = BRep_Tool::Curve(edge,L,First,Last);
686  curve->D1((First+Last)/2.0,PMid,TangMid);
687  TangMid.Normalize();
688  Handle(Geom_Surface) this_surface = BRep_Tool::Surface(face);
689  ShapeAnalysis_Surface self_projector(this_surface);
690  gp_Pnt2d self_proj_params = self_projector.ValueOfUV(PMid, 1e-7);
691  GeomLProp_SLProps self_props(this_surface, self_proj_params.X(), self_proj_params.Y(),1, 1e-7);
692  gp_Dir self_Normal = self_props.Normal();
693  //cout<<"Face "<<face_count<<" Point "<<edge_count<<": "<<Pnt(PMid)<<endl;
694 
695  TopExp_Explorer innerFaceExplorer(sh, TopAbs_FACE);
696  TopoDS_Face innerFace;
697  unsigned int inner_face_count = 0;
698  double minDistance = 1e7;
699  gp_Pnt nearest_projection;
700  unsigned int projFaceID;
701  gp_Dir Normal;
702  while (innerFaceExplorer.More())
703  {
704  if ((inner_face_count != face_count) && (!facesBndBoxes[inner_face_count].IsOut(PMid)) )
705  {
706  innerFace = TopoDS::Face(innerFaceExplorer.Current());
707  BRepExtrema_DistShapeShape distSS(innerFace,BRepBuilderAPI_MakeVertex(PMid));
708  distSS.Perform();
709  if (distSS.IsDone())
710  {
711  //cout<<"Distance Eval: "<<distSS.Value()<<" Point: "<<Pnt(distSS.PointOnShape1(1))<<endl;
712  }
713  else
714  {
715  cout<<"WARNING: Distance Eval Computation FAILED: should stop everything here "<<endl;
716  }
717  double U1,U2,V1,V2;
718  Handle(Geom_Surface) SurfToProj = BRep_Tool::Surface(innerFace);
719  SurfToProj->Bounds(U1,U2,V1,V2);
720  //cout<<"Inner Face "<<inner_face_count<<" Center ("<<Pnt(SurfToProj->Value((U1+U2)/2.0,(V1+V2)/2.0))<<")"<<endl;
721  ShapeAnalysis_Surface projector(SurfToProj);
722  gp_Pnt2d proj_params = projector.ValueOfUV(distSS.PointOnShape1(1), 1e-7);
723  gp_Pnt projection;
724  SurfToProj->D0(proj_params.X(),proj_params.Y(),projection);
725  if (distSS.Value() < minDistance)
726  {
727  minDistance = distSS.Value();
728  nearest_projection = distSS.PointOnShape1(1);
729  projFaceID=inner_face_count;
730  GeomLProp_SLProps props(SurfToProj, proj_params.X(), proj_params.Y(),1, 1e-7);
731  Normal = props.Normal();
732  }
733 
734  }
735  innerFaceExplorer.Next();
736  ++inner_face_count;
737  }
738 
739  //cout<<"Nearest Projection "<<Pnt(nearest_projection)<<" on face "<<projFaceID<<endl;
740  if (minDistance < LinTol)
741  {
742  //cout<<"Fake edge? "<<endl;
743  //cout<<"n_a("<<self_Normal.X()<<","<<self_Normal.Y()<<","<<self_Normal.Z()<<")"<<endl;
744  //cout<<"n_b("<<Normal.X()<<","<<Normal.Y()<<","<<Normal.Z()<<")"<<endl;
745  //cout<<"Angle "<<180/PI*self_Normal.Angle(Normal)<<" or ";
746  //cout<<180.0/PI*self_Normal.Angle(-Normal)<<endl;
747 
748  if ( fmin(fabs(180/PI*self_Normal.Angle(Normal)),
749  fabs(180/PI*self_Normal.Angle(-Normal))) < 5.0)
750  {
751  //cout<<"From closest point and normal could be the edge is fake "<<face_count<<"----->"<<projFaceID<<endl;
752 
753  // we try here to understand if the normals are "aligned" because the faces have smooth
754  // junction or instead they form a cusp
755  innerFaceExplorer.ReInit();
756  for (unsigned int kk=0; kk<projFaceID; ++kk)
757  innerFaceExplorer.Next();
758  innerFace = TopoDS::Face(innerFaceExplorer.Current());
759  Handle(Geom_Surface) SurfToProj = BRep_Tool::Surface(innerFace);
760  gp_Vec normal_vec(Normal);
761  gp_Vec cross_vec = TangMid.Crossed(normal_vec);
762  gp_Pnt P_1(PMid.X()+50*LinTol*cross_vec.X(),PMid.Y()+50*LinTol*cross_vec.Y(),PMid.Z()+50*LinTol*cross_vec.Z());
763  gp_Pnt P_2(PMid.X()-50*LinTol*cross_vec.X(),PMid.Y()-50*LinTol*cross_vec.Y(),PMid.Z()-50*LinTol*cross_vec.Z());
764  //cout<<"Point: "<<Pnt(PMid)<<endl;
765  //cout<<"Normal: "<<normal_vec.X()<<" "<<normal_vec.Y()<<" "<<normal_vec.Z()<<endl;
766  //cout<<"Edge Tangent: "<<TangMid.X()<<" "<<TangMid.Y()<<" "<<TangMid.Z()<<endl;
767  //cout<<"P1: "<<Pnt(P_1)<<" P2: "<<Pnt(P_2)<<endl;
768  BRepExtrema_DistShapeShape distSS1(innerFace,BRepBuilderAPI_MakeVertex(P_1));
769  distSS1.Perform();
770  double distance1 = distSS1.Value();
771  gp_Pnt proj_point1 = distSS1.PointOnShape1(1);
772  distSS1.LoadS2(BRepBuilderAPI_MakeVertex(P_2));
773  distSS1.Perform();
774  if (distSS1.Value() < distance1)
775  proj_point1 = distSS1.PointOnShape1(1);
776  //cout<<"F1 P1 Dist: "<<distance1<<" F1 P2 Dist: "<<distSS1.Value()<<endl;
777  BRepExtrema_DistShapeShape distSS2(face,BRepBuilderAPI_MakeVertex(P_1));
778  distSS2.Perform();
779  double distance2 = distSS2.Value();
780  gp_Pnt proj_point2 = distSS2.PointOnShape1(1);
781  distSS2.LoadS2(BRepBuilderAPI_MakeVertex(P_2));
782  distSS2.Perform();
783  if (distSS2.Value() < distance2)
784  proj_point2 = distSS2.PointOnShape1(1);
785  //cout<<"F2 P1 Dist: "<<distance2<<" F2 P2 Dist: "<<distSS2.Value()<<endl;
786 
787  gp_Vec v1(PMid,proj_point1);
788  gp_Vec v2(PMid,proj_point2);
789  //cout<<"V1: "<<v1.X()<<" "<<v1.Y()<<" "<<v1.Z()<<endl;
790  //cout<<"V2: "<<v2.X()<<" "<<v2.Y()<<" "<<v2.Z()<<endl;
791  if ( fabs(180/PI*v1.Angle(v2)) > 90)
792  {
793  //cout<<"Yes, the edge is fake "<<face_count<<"----->"<<projFaceID<<endl;
794  faces_neighbors_sets[face_count].insert(projFaceID);
795  }
796  else
797  {
798  //cout<<"No, the edge is sharp "<<endl;
799  feature_edges.push_back(edge);
800  }
801  }
802  else
803  {
804  //cout<<"No, the edge is sharp "<<endl;
805  feature_edges.push_back(edge);
806  }
807  }
808  else
809  {
810  //cout<<"Outer edge "<<endl;
811  feature_edges.push_back(edge);
812  }
813 
814  }
815  edgeExplorer.Next();
816  ++edge_count;
817  }
818  faceExplorer.Next();
819  ++face_count;
820  }
821 
822  cout<<endl;
823  cout<<"Let's group faces into colors "<<endl;
824  cout<<endl;
825  for (unsigned int i=0; i<num_faces; ++i)
826  {
827  cout<<"Face "<<i<<": ";
828  for (std::set<unsigned int>::iterator pos=faces_neighbors_sets[i].begin(); pos!=faces_neighbors_sets[i].end(); ++pos)
829  cout<<" "<<*pos;
830  cout<<endl;
831  }
832  std::set < std::set<unsigned int> > colors;
833  for (unsigned int k=0; k<num_faces; ++k)
834  {
835  std::set<unsigned int> color=faces_neighbors_sets[k];
836  unsigned int prev_size = color.size();
837  unsigned int new_size = color.size()+1;
838  while (prev_size != new_size)
839  {
840  prev_size=color.size();
841  for (unsigned int i=0; i<num_faces; ++i)
842  {
843  for (std::set<unsigned int>::iterator pos=color.begin(); pos!=color.end(); ++pos)
844  if (faces_neighbors_sets[i].count(*pos) > 0)
845  {
846  for (std::set<unsigned int>::iterator pos=faces_neighbors_sets[i].begin(); pos!=faces_neighbors_sets[i].end(); ++pos)
847  color.insert(*pos);
848  break;
849  }
850  }
851  new_size=color.size();
852  }
853  colors.insert(color);
854  }
855 
856 
857  /*
858  IGESControl_Controller::Init();
859  IGESControl_Writer ICW ("MM", 0);
860  for (unsigned int i=0; i<feature_edges.size(); ++i)
861  Standard_Boolean ok = ICW.AddShape (feature_edges[i]);
862  ICW.ComputeModel();
863  Standard_Boolean OK = ICW.Write ("feature_edges.igs");
864  */
865 
866  // trying to organize the edges in feature_edges vector into a limited number of
867  // curves
868  std::vector<bool> active_flag(feature_edges.size(),true);
869  std::vector<gp_Pnt> start_points(feature_edges.size());
870  std::vector<gp_Pnt> mid_points(feature_edges.size());
871  std::vector<gp_Pnt> end_points(feature_edges.size());
872  std::vector<gp_Dir> start_tangents(feature_edges.size());
873  std::vector<gp_Dir> end_tangents(feature_edges.size());
874  for (unsigned int i=0; i<feature_edges.size(); ++i)
875  {
876  TopLoc_Location L;
877  Standard_Real First;
878  Standard_Real Last;
879  Handle(Geom_Curve) curve = BRep_Tool::Curve(feature_edges[i],L,First,Last);
880  gp_Pnt PMid;
881  curve->D0(First,start_points[i]);
882  curve->D0(Last,end_points[i]);
883  GeomLProp_CLProps curve_props_First(curve, First,1, LinTol);
884  GeomLProp_CLProps curve_props_Last(curve, Last, 1, LinTol);
885  if (curve_props_First.IsTangentDefined() == false )
886  std::cout<<"Warning! Tangent vector at start of edge "<<i<<" is undefined!"<<std::endl;
887  if (curve_props_Last.IsTangentDefined() == false )
888  std::cout<<"Warning! Tangent vector at end of edge "<<i<<" is undefined!"<<std::endl;
889  curve_props_First.Tangent(start_tangents[i]);
890  curve_props_Last.Tangent(end_tangents[i]);
891  GeomAdaptor_Curve AC(curve);
892  Standard_Real arcLength = GCPnts_AbscissaPoint::Length(AC,First,Last);
893  if (arcLength < LinTol)
894  active_flag[i] = false;
895  //cout<<"arcLength "<<arcLength<<endl;
896  GCPnts_AbscissaPoint AP(AC, arcLength/2.0, First);
897  //cout<<"direction*arcLength*distance "<<direction*arcLength*distance<<endl;
898  Standard_Real t2 = AP.Parameter();
899  AssertThrow((First <= t2) &&
900  (t2 <= Last),
901  ExcMessage("Parameter 3 is out of range!"));
902  mid_points[i] = AC.Value(t2);
903 
904  /*
905  std::cout<<std::endl;
906  std::cout<<i<<std::endl;
907  std::cout<<"Start Point: "<<Pnt(start_points[i])<<std::endl;
908  std::cout<<"Mid Point: "<<Pnt(mid_points[i])<<std::endl;
909  std::cout<<"End Point: "<<Pnt(end_points[i])<<std::endl;
910  std::cout<<"Start Tangent: "<<start_tangents[i].X()<<" "<<start_tangents[i].Y()<<" "<<start_tangents[i].Z()<<std::endl;
911  std::cout<<"End Tangent: "<<end_tangents[i].X()<<" "<<end_tangents[i].Y()<<" "<<end_tangents[i].Z()<<std::endl;
912  std::cout<<"F: "<<First<<" "<<" L: "<<Last<<" Or: "<<feature_edges[i].Orientation()<<std::endl;
913  std::cout<<"F?: "<<curve_props_First.IsTangentDefined()<<" "<<" L?: "<<curve_props_Last.IsTangentDefined()<<std::endl;
914  */
915  }
916 
917  // we first take out all possible copies of same edge: here detected as
918  // edges with same end, mid and last point, the procedude could be changed if needed
919  for (unsigned int i=0; i<feature_edges.size(); ++i)
920  if (active_flag[i])
921  {
922  for (unsigned int j=i+1; j<feature_edges.size(); ++j)
923  if (mid_points[i].IsEqual(mid_points[j],LinTol))
924  if (start_points[i].IsEqual(start_points[j],LinTol) || start_points[i].IsEqual(end_points[j],LinTol))
925  if (end_points[i].IsEqual(end_points[j],LinTol) || end_points[i].IsEqual(start_points[j],LinTol))
926  active_flag[j] = false;
927  }
928 
929  std::vector<TopoDS_Edge> unified_edge_vector;
930  std::vector<Handle(Geom_Curve)> unified_curve_handles_vector;
931  unsigned int unified_edges_count=0;
932 
933  for (unsigned int k=0; k<feature_edges.size(); ++k)
934  if (active_flag[k])
935  {
936  //std::cout<<"Unified edge "<<unified_edges_count<<" is to be grown from edge: "<<k<<std::endl;
937  std::set<unsigned int> joined_edges;
938  joined_edges.insert(k);
939  active_flag[k] = false;
940  gp_Pnt curve_start_point = start_points[k];
941  gp_Pnt curve_end_point = end_points[k];
942  gp_Vec curve_start_tangent = start_tangents[k];
943  gp_Vec curve_end_tangent = end_tangents[k];
944  unsigned int added_count = 1;
945 
946  while (added_count > 0)
947  {
948  added_count = 0;
949  for (unsigned int i=0; i<feature_edges.size(); ++i)
950  if (active_flag[i])
951  {
952  if (curve_end_point.IsEqual(start_points[i],LinTol) && (curve_end_tangent.Angle(start_tangents[i]) < AngTol))
953  {
954  //cout<<"aFOUND! "<<i<<endl;
955  joined_edges.insert(i);
956  active_flag[i] = false;
957  curve_end_point = end_points[i];
958  curve_end_tangent = end_tangents[i];
959  added_count++;
960  }
961  else if (curve_end_point.IsEqual(end_points[i],LinTol) && (PI-curve_end_tangent.Angle(end_tangents[i]) < AngTol))
962  {
963  //cout<<"bFOUND! "<<i<<endl;
964  joined_edges.insert(i);
965  active_flag[i] = false;
966  curve_end_point = start_points[i];
967  curve_end_tangent = -start_tangents[i];
968  added_count++;
969  }
970  else if (curve_start_point.IsEqual(start_points[i],LinTol) && (PI-curve_start_tangent.Angle(start_tangents[i]) < AngTol))
971  {
972  //cout<<"cFOUND! "<<i<<endl;
973  joined_edges.insert(i);
974  active_flag[i] = false;
975  curve_start_point = end_points[i];
976  curve_start_tangent = -end_tangents[i];
977  added_count++;
978  }
979  else if (curve_start_point.IsEqual(end_points[i],LinTol) && (curve_start_tangent.Angle(end_tangents[i]) < AngTol))
980  {
981  //cout<<"dFOUND! "<<i<<endl;
982  joined_edges.insert(i);
983  active_flag[i] = false;
984  curve_start_point = start_points[i];
985  curve_start_tangent = start_tangents[i];
986  added_count++;
987  }
988  }
989  //std::cout<<"Added: "<<added_count<<endl;
990  if (curve_start_point.IsEqual(curve_end_point,LinTol))
991  added_count = 0;
992  }// end while
993 
994  std::vector<TopoDS_Edge> edges_to_be_joined;
995  std::cout<<"Unified edge "<<unified_edges_count<<" is grown from edge: "<<k<<std::endl;
996  for (std::set<unsigned int>::iterator pos=joined_edges.begin(); pos!=joined_edges.end(); ++pos)
997  {
998  std::cout<<*pos<<" ";
999  edges_to_be_joined.push_back(feature_edges[*pos]);
1000  }
1001  std::cout<<std::endl;
1002 
1003  // after we found all the "joinable" edges, we join them
1004  TopLoc_Location L;
1005  Standard_Real First;
1006  Standard_Real Last;
1007  unsigned int numKeelEdges = edges_to_be_joined.size();
1008  Handle(Geom_Curve) curve1 = BRep_Tool::Curve(edges_to_be_joined[0],L,First,Last);
1009  //Handle(Geom_BoundedCurve) bcurve1 = Handle(Geom_BoundedCurve)::DownCast(curve1);
1010  Handle(Geom_TrimmedCurve) bcurve1 = new Geom_TrimmedCurve(curve1, First, Last);
1011 
1012  GeomConvert_CompCurveToBSplineCurve convert_keel_bspline(bcurve1,Convert_TgtThetaOver2);
1013 
1014  bool check = false, one_added = true, one_failed=true;
1015  vector<bool> added(numKeelEdges, false);
1016  added[0] = true;
1017  while (one_added == true)
1018  {
1019  one_added = false;
1020  one_failed = false;
1021  for (unsigned int ii=1; ii<numKeelEdges; ++ii)
1022  if (added[ii] == false)
1023  {
1024  //cout<<"Curve "<<ii<<" of "<<numKeelEdges<<endl;
1025  Handle(Geom_Curve) curve = BRep_Tool::Curve(edges_to_be_joined[ii],L,First,Last);
1026  Handle(Geom_TrimmedCurve) bcurve = new Geom_TrimmedCurve(curve, First, Last);
1027  gp_Pnt PIn, PMid, PFin;
1028  //First = curve->FirstParameter();
1029  //Last = curve->LastParameter();
1030  curve->D0(First,PIn);
1031  curve->D0(Last,PFin);
1032  curve->D0((First+Last)/2.0,PMid);
1033  //cout<<"To be added "<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<endl;
1034  Handle(Geom_Curve) temp = convert_keel_bspline.BSplineCurve();
1035  First = temp->FirstParameter();
1036  Last = temp->LastParameter();
1037  temp->D0(First,PIn);
1038  temp->D0(Last,PFin);
1039  temp->D0((First+Last)/2.0,PMid);
1040  //cout<<"Keel "<<Pnt(PIn)<<" | "<<Pnt(PMid)<<" | "<<Pnt(PFin)<<endl;
1041  //Handle(Geom_BoundedCurve) bcurve = Handle(Geom_BoundedCurve)::DownCast(curve);
1042  check = convert_keel_bspline.Add(bcurve,LinTol,0,1,0);
1043  one_failed = one_failed || (check == false);
1044  one_added = one_added || (check == true);
1045  added[ii] = check;
1046  }
1047  }
1048 
1049  AssertThrow(one_failed == false,
1050  ExcMessage("Bspline conversion has failed."));
1051 
1052  Handle(Geom_BSplineCurve) equiv_keel_bspline = convert_keel_bspline.BSplineCurve();
1053 
1054  Handle(Geom_Curve) bspline = convert_keel_bspline.BSplineCurve();
1055  cout<<Pnt(bspline->Value(bspline->FirstParameter()))<<" and "<<Pnt(bspline->Value(bspline->LastParameter()))<<endl;
1056  unified_curve_handles_vector.push_back(bspline);
1057 
1058 
1059  //if (bspline->IsCN(1))
1060  // cout<<"Transom curve is at least C1"<<endl;
1061  //else
1062  // cout<<"Transom curve is not C1"<<endl;
1063 
1064  TopoDS_Edge unified_edge = BRepBuilderAPI_MakeEdge(bspline);
1065  unified_edge_vector.push_back(unified_edge);
1066 
1067  IGESControl_Controller::Init();
1068  IGESControl_Writer ICW ("MM", 0);
1069  Standard_Boolean ok = ICW.AddShape(unified_edge);
1070  ICW.ComputeModel();
1071  std::string filename = ( "unified_edges_" +
1072  Utilities::int_to_string(unified_edges_count+1) +
1073  ".igs" );
1074  std::ofstream file(filename.c_str());
1075  Standard_Boolean OK = ICW.Write (file);
1076  unified_edges_count++;
1077  } // end for
1078 
1079 
1080 
1081  cout<<"Number of unified edges generated: "<<unified_edge_vector.size()<<endl;
1082 
1083  BRep_Builder builder;
1084 
1085  std::vector<TopoDS_Compound> color_compounds;
1086 
1087  unsigned int color_count=0;
1088  cout<<"Color "<<color_count<<"?"<<endl;
1089  for (std::set< std::set<unsigned int> >::iterator posExt=colors.begin(); posExt!=colors.end(); ++posExt)
1090  {
1091  cout<<"COLOR "<<color_count<<":";
1092  for (std::set<unsigned int>::iterator pos= (*posExt).begin(); pos!= (*posExt).end(); ++pos)
1093  {
1094  cout<<" "<<*pos;
1095  }
1096  cout<<endl;
1097 
1098  faceExplorer.Init(sh, TopAbs_FACE);
1099  TopoDS_Compound color_compound;
1100  builder.MakeCompound(color_compound);
1101 
1102  unsigned int face_count = 0;
1103  cout<<"Added Faces :";
1104  while (faceExplorer.More())
1105  {
1106  face = TopoDS::Face(faceExplorer.Current());
1107  if (posExt->count(face_count) == 1)
1108  {
1109  builder.Add(color_compound,face);
1110  cout<<" "<<face_count;
1111  }
1112  faceExplorer.Next();
1113  ++face_count;
1114  }
1115  cout<<endl;
1116  color_compounds.push_back(color_compound);
1117 
1118  IGESControl_Controller::Init();
1119  IGESControl_Writer ICW ("MM", 0);
1120  Standard_Boolean ok = ICW.AddShape(color_compounds[color_count]);
1121  ICW.ComputeModel();
1122  std::string filename = ( "color_compound_" +
1123  Utilities::int_to_string(color_count+1) +
1124  ".igs" );
1125  std::ofstream file(filename.c_str());
1126  Standard_Boolean OK = ICW.Write (file);
1127 
1128  ++color_count;
1129 
1130 
1131  // let's try and mesh them here
1132  Standard_Integer deg = 3;
1133  Standard_Integer n_points = 30;
1134  Standard_Integer n_iter = 6;
1135  Standard_Real tol_3d = 1e-4;
1136  Standard_Real tol_2d = 1e-5;
1137  Standard_Real tol_ang = 0.001;
1138  Standard_Real tol_curv = 0.001;
1139  GeomPlate_BuildPlateSurface plate_surface_builder(deg, n_points, n_iter, tol_2d, tol_3d, tol_ang, tol_curv, Standard_False);
1140  plate_surface_builder.SetNbBounds(unified_edge_vector.size());
1141  for (unsigned int i=0; i<unified_edge_vector.size(); ++i)
1142  {
1143  TopoDS_Edge edge = unified_edge_vector[i];
1144  TopLoc_Location L;
1145  Standard_Real First;
1146  Standard_Real Last;
1147  Handle(Geom_Curve) curve = unified_curve_handles_vector[i]; //BRep_Tool::Curve(feature_edges[i],L,First,Last);
1148  cout<<Pnt(curve->Value(curve->FirstParameter()))<<" and "<<Pnt(curve->Value(curve->LastParameter()))<<endl;
1149  //cout<<Pnt(curve->Value(First))<<" and "<<Pnt(curve->Value(Last))<<endl;
1150  GeomAdaptor_HCurve geom_adaptor_hcurve(curve);
1151  const Handle(GeomAdaptor_HCurve)& aHC = new GeomAdaptor_HCurve(geom_adaptor_hcurve);
1152  Handle (GeomPlate_CurveConstraint) aConst = new GeomPlate_CurveConstraint (aHC, 0, n_points, tol_3d);
1153  plate_surface_builder.Add(aConst);
1154  gp_Pnt first_point;
1155  gp_Pnt last_point;
1156  aConst->D0(aConst->FirstParameter(), first_point);
1157  aConst->D0(aConst->LastParameter(), last_point);
1158  cout<<"## "<<Pnt(first_point)<<" and "<<Pnt(last_point)<<endl;
1159  }
1160  cout<<"Here"<<endl;
1161  plate_surface_builder.Perform();
1162 
1163 
1164  if (plate_surface_builder.IsDone())
1165  {
1166  cout<<"Made it! Error: "<<plate_surface_builder.G0Error()<<endl;
1167  Handle (GeomPlate_Surface) plate_surf = plate_surface_builder.Surface();
1168  Standard_Real dmax = plate_surface_builder.G0Error();
1169  TColgp_SequenceOfXY aS2d;
1170  TColgp_SequenceOfXYZ aS3d;
1171  plate_surface_builder.Disc2dContour (40, aS2d);
1172  plate_surface_builder.Disc3dContour (40, 0, aS3d);
1173  for (unsigned i=0; i<40; ++i)
1174  {
1175  gp_XY uv_point = aS2d.Value(i+1);
1176  gp_XYZ xyz_point = aS3d.Value(i+1);
1177  cout<<i<<endl;
1178  cout<<"("<<uv_point.X()<<","<<uv_point.Y()<<")"<<endl;
1179  cout<<"("<<xyz_point.X()<<","<<xyz_point.Y()<<","<<xyz_point.Z()<<")"<<endl;
1180  }
1181  //Standard_Real aMax = Max (aTol3d, 10. * aDMax);
1182  GeomPlate_PlateG0Criterion criterion (aS2d, aS3d, tol_3d);
1183  Standard_Integer max_bezier_pieces = 50;
1184  GeomPlate_MakeApprox make_approx(plate_surf, criterion, tol_3d, max_bezier_pieces, deg, GeomAbs_C0, 1.1);
1185  //GeomPlate_MakeApprox make_approx(plate_surf, tol_3d, max_bezier_pieces, deg, dmax, 0, GeomAbs_C0, 3.0);
1186  Handle(Geom_BSplineSurface) bspline_surf = make_approx.Surface();
1187  IGESControl_Controller::Init();
1188  IGESControl_Writer ICW2 ("MM", 0);
1189  Standard_Boolean ok = ICW2.AddGeom(bspline_surf);
1190  ICW2.ComputeModel();
1191  std::string new_filename = ( "approx_surface" +
1193  ".igs" );
1194  std::ofstream file(new_filename.c_str());
1195  Standard_Boolean OK = ICW2.Write (file);
1196 
1197 
1198  cout<<"Re-Made it!"<<endl;
1199 
1200 
1201  BRepBuilderAPI_MakeWire wireMaker;
1202 
1203  for (unsigned int i = 0; i< unified_curve_handles_vector.size(); ++i)
1204  {
1205  Handle(Geom_Curve) curve = unified_curve_handles_vector[i];
1206  TopoDS_Edge myEdge = BRepBuilderAPI_MakeEdge(curve);
1207  wireMaker.Add(myEdge);
1208  }
1209 
1210  TopoDS_Wire myWire = wireMaker.Wire();
1211  BRepBuilderAPI_MakeFace faceMaker(bspline_surf, myWire, Standard_True);
1212  TopoDS_Face trimmed_approx_face = faceMaker.Face();
1213 
1214  IGESControl_Controller::Init();
1215  IGESControl_Writer ICW3 ("MM", 0);
1216  Standard_Boolean ook = ICW3.AddShape(trimmed_approx_face);
1217  ICW3.ComputeModel();
1218  std::string neww_filename = ( "trimmed_approx_surface" +
1220  ".igs" );
1221  std::ofstream file2(neww_filename.c_str());
1222  Standard_Boolean OOK = ICW3.Write (file2);
1223  BRepMesh_IncrementalMesh (trimmed_approx_face, 0.7f);
1224 
1225  //BRepMesh::Mesh(trimmed_approx_face, 0.7f);
1226 
1227  BRepBuilderAPI_MakeFace faceMaker2(bspline_surf, 1e-6);
1228  TopoDS_Face aFace = faceMaker2.Face();
1229  TopLoc_Location loc;
1230  loc.Identity();
1231  Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(aFace, loc);
1232 
1233 
1234 
1235 
1236  if (tri.IsNull())
1237  {
1238  cout<<"Tringulation didn't work"<<endl;
1239  Bnd_Box bndBox;
1240  BRepBndLib::Add(trimmed_approx_face, bndBox);
1241  cout<<"Extent: "<<sqrt(bndBox.SquareExtent())<<endl;
1242  //bndBox.Enlarge(100*LinTol);
1243  //BRepMesh_FastDiscret mesh_fast_discret(0.0000001,trimmed_approx_face,bndBox, 0.1, Standard_True, Standard_True, Standard_True, Standard_True);
1244  //cout<<"Vertices: "<<mesh_fast_discret.NbVertices()<<endl;
1245  BRepMesh_IncrementalMesh aMesh(aFace, 0.25);
1246  aMesh.Perform();
1247  cout<<"** "<<aMesh.IsDone()<<endl;
1248  cout<<aMesh.GetStatusFlags()<<endl;
1249 
1250  //BRepMesh::Mesh(trimmed_approx_face, 0.25);
1251  }
1252  tri = BRep_Tool::Triangulation(aFace, loc);
1253  if (tri.IsNull())
1254  {
1255  cout<<"Tringulation didn't work AGAIN"<<endl;
1256  }
1257  const TColgp_Array1OfPnt &nodes = tri->Nodes();
1258  cout<<nodes.Upper()<<endl;
1259  }
1260 
1261 
1262 
1263  }
1264 
1265 
1266 
1267 
1268 
1269  } // end method
1270 
1271 } // end namespace
1272 
1273 
Handle_Geom_Curve interpolation_curve(std::vector< Point< 3 > > &curve_points)
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
STL namespace.
#define AssertThrow(cond, exc)
TopoDS_Shape merge_surfaces(const TopoDS_Shape &, const double)
static::ExceptionBase & ExcMessage(std::string arg1)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
dealii::Point< 3 > Pnt(const gp_Pnt &p)
Convert OpenCascade point into.
Definition: occ_utilities.h:76
void feature_edges_detection()
TopoDS_Shape extract_transom_edges(const TopoDS_Shape &in_shape, const unsigned int num_transom_edges, const double tolerance)
We collect in this namespace all utilities which operate on OpenCascade entities which don't need cla...
TopoDS_Shape read_IGES(string filename, double scale_factor)
Read IGES files and translate.
Handle(Geom_Curve) NumericalTowingTank
void intersect_plane(const TopoDS_Shape &in_shape, TopoDS_Shape &out_shape, const double c_x, const double c_y, const double c_z, const double c, const double tolerance)
Perform the intersection of the.
TopoDS_Shape extract_xz_edges(const TopoDS_Shape &in_shape, const double tolerance, const unsigned int max_num_edges)
bool point_compare(const dealii::Point< 3 > &p1, const dealii::Point< 3 > &p2, const dealii::Point< 3 > &direction)
Definition: occ_utilities.h:91
Handle_Geom_Curve interpolation_curve_points_sort(std::vector< Point< 3 > > &curve_points, Point< 3 > direction)