1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <GEOMImpl_PipeDriver.hxx>
25 #include <GEOMImpl_IPipeDiffSect.hxx>
26 #include <GEOMImpl_IPipeShellSect.hxx>
27 #include <GEOMImpl_IPipeBiNormal.hxx>
28 #include <GEOMImpl_IPipe.hxx>
29 #include <GEOMImpl_IPipePath.hxx>
30 #include <GEOMImpl_GlueDriver.hxx>
31 #include <GEOMImpl_Types.hxx>
33 #include <GEOM_Function.hxx>
35 #include <GEOMUtils.hxx>
37 #include <ShapeAnalysis_FreeBounds.hxx>
38 #include <ShapeAnalysis_Edge.hxx>
39 #include <ShapeFix_Face.hxx>
40 #include <ShapeFix_Shell.hxx>
41 #include <ShapeFix_Shape.hxx>
42 #include <ShapeFix_ShapeTolerance.hxx>
44 #include <BRep_Tool.hxx>
45 #include <BRep_Builder.hxx>
46 #include <BRepBuilderAPI_Copy.hxx>
47 #include <BRepBuilderAPI_MakeFace.hxx>
48 #include <BRepBuilderAPI_MakeWire.hxx>
49 #include <BRepBuilderAPI_Sewing.hxx>
50 #include <BRepCheck_Analyzer.hxx>
51 #include <BRepGProp.hxx>
52 #include <GeomFill_Trihedron.hxx>
53 #include <GeomFill_CorrectedFrenet.hxx>
54 #include <BRepOffsetAPI_MakePipe.hxx>
55 #include <BRepOffsetAPI_MakePipeShell.hxx>
59 #include <TopExp_Explorer.hxx>
61 #include <TopoDS_Wire.hxx>
62 #include <TopoDS_Edge.hxx>
63 #include <TopoDS_Shape.hxx>
64 #include <TopoDS_Solid.hxx>
65 #include <TopoDS_Shell.hxx>
66 #include <TopoDS_Face.hxx>
67 #include <TopoDS_Compound.hxx>
68 #include <TopTools_SequenceOfShape.hxx>
69 #include <TopTools_HSequenceOfShape.hxx>
70 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
71 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
72 #include <TopTools_ListIteratorOfListOfShape.hxx>
74 #include <GProp_GProps.hxx>
76 #include <GeomAPI_ProjectPointOnCurve.hxx>
77 #include <GeomAPI_Interpolate.hxx>
78 #include <Geom_TrimmedCurve.hxx>
79 #include <Geom_Plane.hxx>
80 #include <Geom_RectangularTrimmedSurface.hxx>
81 #include <Geom_BezierSurface.hxx>
82 #include <Geom_Line.hxx>
83 #include <Geom_Conic.hxx>
84 #include <Geom_BSplineCurve.hxx>
85 #include <Geom_BSplineSurface.hxx>
86 #include <GeomAdaptor_HCurve.hxx>
87 #include <GeomFill_BSplineCurves.hxx>
88 #include <GeomConvert_ApproxCurve.hxx>
89 #include <GeomConvert.hxx>
91 #include <TColgp_SequenceOfPnt.hxx>
92 #include <TColgp_HArray1OfPnt.hxx>
93 #include <TColgp_Array2OfPnt.hxx>
94 #include <TColStd_HSequenceOfTransient.hxx>
96 #include <Precision.hxx>
98 #include <Standard_NullObject.hxx>
99 #include <Standard_TypeMismatch.hxx>
100 #include <Standard_ConstructionError.hxx>
102 #include "utilities.h"
105 //=======================================================================
108 //=======================================================================
109 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
111 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
115 //=======================================================================
116 //function : GEOMImpl_PipeDriver
118 //=======================================================================
119 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
123 //=======================================================================
124 //function : EvaluateBestSweepMode
125 //purpose : auxilary for right call of MakePipe and MakePipeShell
126 //=======================================================================
127 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
129 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
131 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
132 for (; Explo.More(); Explo.Next())
134 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
135 Standard_Real fpar, lpar;
136 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
137 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
138 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
140 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
141 aCorrFrenet->SetCurve(GAHcurve);
142 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
143 if (aMode == GeomFill_IsDiscreteTrihedron)
148 if (aMode == GeomFill_IsCorrectedFrenet)
155 //=======================================================================
156 //function : BuildPipeShell
157 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
158 // mode. Returns Standard_True if the building is done successfully.
159 //=======================================================================
160 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
164 Standard_Boolean isDone = theBuilder.IsDone();
167 // Try to use Descrete Trihedron mode.
168 theBuilder.SetDiscreteMode();
170 isDone = theBuilder.IsDone();
176 //=======================================================================
177 //function : FillForOtherEdges
178 //purpose : auxilary for CreatePipeForShellSections()
179 //=======================================================================
180 static bool FillForOtherEdges(const TopoDS_Shape& F1,
181 const TopoDS_Shape& E1,
182 const TopoDS_Shape& V1,
183 TopTools_IndexedDataMapOfShapeShape& FF)
185 //cout<<"FillForOtherEdges"<<endl;
186 // find other pairs for vertexes and edges
187 // creating map of vertex edges for both faces
188 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
189 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
190 if (!FF.Contains(F1))
191 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
192 if (!FF.Contains(E1))
193 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
194 if (!FF.Contains(V1))
195 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
196 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
197 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
198 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
199 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
200 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
202 TopoDS_Edge ES1 = TopoDS::Edge(E1);
203 TopoDS_Edge ES2 = TopoDS::Edge(E2);
204 TopoDS_Shape VS1 = V1;
205 TopoDS_Shape VS2 = V2;
207 ShapeAnalysis_Edge sae;
209 if (!aMapVertEdge1.Contains(VS1))
210 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
211 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
212 //TopoDS_Shape E1next;
213 TopTools_ListIteratorOfListOfShape anIter1(aList1);
214 if (anIter1.Value().IsSame(ES1)) {
217 //E1next = anIter1.Value();
218 if (!aMapVertEdge2.Contains(VS2))
219 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
220 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
221 //TopoDS_Shape E2next;
222 TopTools_ListIteratorOfListOfShape anIter2(aList2);
223 if (anIter2.Value().IsSame(ES2)) {
226 //E2next = anIter2.Value();
227 //ES1 = TopoDS::Edge(E1next);
228 //ES2 = TopoDS::Edge(E2next);
229 ES1 = TopoDS::Edge(anIter1.Value());
230 ES2 = TopoDS::Edge(anIter2.Value());
231 if (!FF.Contains(ES1)) {
234 if (VS1.IsSame(sae.FirstVertex(ES1)))
235 VS1 = sae.LastVertex(ES1);
237 VS1 = sae.FirstVertex(ES1);
238 if (VS2.IsSame(sae.FirstVertex(ES2)))
239 VS2 = sae.LastVertex(ES2);
241 VS2 = sae.FirstVertex(ES2);
244 if (!FF.Contains(VS1)) {
252 //=======================================================================
253 //function : FillCorrespondingEdges
254 //purpose : auxilary for CreatePipeForShellSections()
255 //=======================================================================
256 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
257 const TopoDS_Shape& FS2,
258 const TopoDS_Vertex& aLoc1,
259 const TopoDS_Vertex& aLoc2,
260 const TopoDS_Wire& aWirePath,
261 TopTools_IndexedDataMapOfShapeShape& FF)
263 //cout<<"FillCorrespondingEdges"<<endl;
264 // find corresponding edges
265 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
266 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
267 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
268 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
269 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
270 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
271 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
272 if (theBestMode == GeomFill_IsDiscreteTrihedron)
273 aBuilder.SetDiscreteMode();
274 aBuilder.Add(aWire1, aLoc1);
275 aBuilder.Add(aWire2, aLoc2);
276 if (!aBuilder.IsReady()) {
280 BuildPipeShell(aBuilder);
282 TopoDS_Shape aShape = aBuilder.Shape();
290 BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
292 ShapeAnalysis_Edge sae;
293 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
294 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
295 TopTools_MapOfShape Vs1,Vs2;
297 exp.Init(FS1, TopAbs_EDGE);
298 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
299 TopoDS_Vertex V11 = sae.FirstVertex(E1);
300 TopoDS_Vertex V21 = sae.LastVertex(E1);
301 gp_Pnt P11 = BRep_Tool::Pnt(V11);
302 gp_Pnt P21 = BRep_Tool::Pnt(V21);
303 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
304 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
305 // find corresponding vertexes from created shape
306 TopoDS_Vertex VN11,VN21;
307 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
308 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
309 gp_Pnt P = BRep_Tool::Pnt(V);
310 if (P.Distance(P11)<tol) {
313 if (P.Distance(P21)<tol) {
317 // find edge contains VN11 and VN21 and corresponding vertexes
318 TopoDS_Vertex VN12,VN22;
319 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
320 TopoDS_Shape F = exp.Current();
321 TopExp_Explorer expe;
323 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
324 TopoDS_Edge E = TopoDS::Edge(expe.Current());
325 TopoDS_Vertex VF = sae.FirstVertex(E);
326 TopoDS_Vertex VL = sae.LastVertex(E);
327 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
333 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
334 TopoDS_Edge E = TopoDS::Edge(expe.Current());
335 TopoDS_Vertex VF = sae.FirstVertex(E);
336 TopoDS_Vertex VL = sae.LastVertex(E);
337 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
339 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
341 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
343 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
349 // find vertexes from FS2 corresponded to VN12 and VN22
350 // and find edge from FS2 contains V12 and V22,
351 // this edge will be corresponded to edge E1
352 TopoDS_Vertex V12,V22;
353 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
354 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
355 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
356 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
358 TopExp_Explorer expe;
359 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
360 TopoDS_Edge E = TopoDS::Edge(expe.Current());
361 TopoDS_Vertex VF = sae.FirstVertex(E);
362 TopoDS_Vertex VL = sae.LastVertex(E);
363 gp_Pnt PF = BRep_Tool::Pnt(VF);
364 gp_Pnt PL = BRep_Tool::Pnt(VL);
365 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
371 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
382 // find other pairs for vertexes and edges
383 // creating map of vertex edges for both faces
384 return FillForOtherEdges(FS1,E1,V21,FF);
389 //=======================================================================
390 //function : FillCorrespondingEdges
391 //purpose : auxilary for CreatePipeShellsWithoutPath()
392 //=======================================================================
393 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
394 const TopoDS_Shape& FS2,
395 const TopoDS_Vertex& aLoc1,
396 const TopoDS_Vertex& aLoc2,
397 TopTools_IndexedDataMapOfShapeShape& FF)
399 //cout<<"FillCorrespondingEdges"<<endl;
401 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
402 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
405 ShapeAnalysis_Edge sae;
406 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
407 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
408 TopTools_MapOfShape Vs1,Vs2;
410 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
413 TopExp_Explorer exp1;
414 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
415 E1 = TopoDS::Edge(exp1.Current());
416 TopoDS_Vertex V1 = sae.FirstVertex(E1);
417 TopoDS_Vertex V2 = sae.LastVertex(E1);
418 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
419 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
420 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
421 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
422 if (P1.Distance(Ptmp1)<tol) {
426 if (P1.Distance(Ptmp2)<tol) {
433 TopoDS_Vertex VE21,VE22;
435 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
436 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
437 TopoDS_Vertex V1 = sae.FirstVertex(E);
438 TopoDS_Vertex V2 = sae.LastVertex(E);
439 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
440 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
441 if (P2.Distance(Ptmp1)<tol) {
453 if (P2.Distance(Ptmp2)<tol) {
467 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
468 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
469 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
470 gp_Vec aDir1(PV21,PE21);
471 gp_Vec aDir2(PV21,PE22);
472 double ang1 = aDir.Angle(aDir1);
473 double ang2 = aDir.Angle(aDir2);
474 if (fabs(ang1)<fabs(ang2)) {
487 // find other pairs for vertexes and edges
488 return FillForOtherEdges(FS1,E1,V21,FF);
491 //=======================================================================
492 //function : FindNextPairOfFaces
493 //purpose : auxilary for CreatePipeForShellSections()
494 //=======================================================================
495 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
496 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
497 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
498 TopTools_IndexedDataMapOfShapeShape& FF,
501 //cout<<"FindNextPairOfFaces"<<endl;
502 TopExp_Explorer anExp;
503 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
504 TopoDS_Shape E1 = anExp.Current();
505 if (!FF.Contains(E1)) {
507 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
509 if (!FF.Contains(E1))
510 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
511 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
512 TopExp_Explorer anExpV;
513 anExpV.Init(E1, TopAbs_VERTEX);
514 TopoDS_Shape V1 = anExpV.Current();
515 if (!FF.Contains(V1)) {
517 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
520 if (!aMapEdgeFaces1.Contains(E1))
521 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
522 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
523 if (aList1.Extent()<2)
525 TopTools_ListIteratorOfListOfShape anIter(aList1);
526 if (anIter.Value().IsEqual(aCurFace)) {
529 TopoDS_Shape F1other = anIter.Value();
530 if (FF.Contains(F1other))
533 if (!FF.Contains(aCurFace))
534 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
535 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
536 if (!aMapEdgeFaces2.Contains(E2))
537 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
538 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
539 if (aList2.Extent()<2) {
541 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
543 TopTools_ListIteratorOfListOfShape anIter2(aList2);
544 if (anIter2.Value().IsEqual(F2)) {
547 TopoDS_Shape F2other = anIter2.Value();
548 FF.Add(F1other,F2other);
550 // add pairs of edges to FF
551 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
554 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
557 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
561 //=======================================================================
562 //function : FindFirstPairFaces
563 //purpose : auxilary for Execute()
564 //=======================================================================
565 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
566 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
567 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
569 //cout<<"FindFirstPairFaces"<<endl;
571 // check if vertexes are sub-shapes of sections
572 gp_Pnt P1 = BRep_Tool::Pnt(V1);
573 gp_Pnt P2 = BRep_Tool::Pnt(V2);
574 TopoDS_Vertex V1new,V2new;
576 double mindist = 1.e10;
577 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
578 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
579 gp_Pnt P = BRep_Tool::Pnt(V);
580 double dist = P1.Distance(P);
587 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
588 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
589 gp_Pnt P = BRep_Tool::Pnt(V);
590 double dist = P2.Distance(P);
597 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
598 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
599 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
600 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
601 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
602 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
604 // replace vertexes if it is needed
605 if (!V1.IsSame(V1new)) {
607 P1 = BRep_Tool::Pnt(V1);
608 MESSAGE (" replace V1");
611 MESSAGE (" not replace V1");
612 if (!V2.IsSame(V2new)) {
614 P2 = BRep_Tool::Pnt(V2);
615 MESSAGE (" replace V2");
618 MESSAGE (" not replace V2");
620 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
621 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
622 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
623 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
625 if (!aMapVertFaces1.Contains(V1))
626 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
627 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
628 TopTools_ListIteratorOfListOfShape anIter1(aList1);
629 FS1 = anIter1.Value();
631 double x1=0., y1=0., z1=0.;
633 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
634 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
635 gp_Pnt P = BRep_Tool::Pnt(V);
641 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
643 TColgp_SequenceOfPnt Ps;
644 TopTools_SequenceOfShape Fs;
645 if (!aMapVertFaces2.Contains(V2))
646 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
647 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
648 TopTools_ListIteratorOfListOfShape anIter2(aList2);
649 for (; anIter2.More(); anIter2.Next()) {
650 TopoDS_Shape F = anIter2.Value();
651 double x2=0., y2=0., z2=0.;
653 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
654 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
655 gp_Pnt P = BRep_Tool::Pnt(V);
661 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
668 double MinAng = M_PI;
670 for (; i<=Fs.Length(); i++) {
671 gp_Vec tmpDir(PM1,Ps(i));
672 double ang = fabs(aDir.Angle(tmpDir));
681 //=======================================================================
682 //function : CreatePipeWithDifferentSections
684 //=======================================================================
685 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
686 (const TopoDS_Wire& theWirePath,
687 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
688 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
689 const Standard_Boolean theWithContact,
690 const Standard_Boolean theWithCorrect)
694 TopoDS_Wire aWirePath = theWirePath;
696 Standard_Integer nbBases = theHSeqBases->Length();
697 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
699 if (nbLocs && nbLocs != nbBases) {
700 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
703 TopTools_SequenceOfShape aSeqBases;
704 TopTools_SequenceOfShape aSeqLocs;
705 TopTools_SequenceOfShape aSeqFaces;
706 Standard_Boolean NeedCreateSolid = Standard_False;
708 Standard_Integer i = 1;
709 for (i = 1; i <= nbBases; i++) {
710 if (theHSeqBases->Value(i).IsNull())
713 // Make copy to prevent modifying of base object 0020766 : EDF 1320
714 TopoDS_Shape aShapeBase;
715 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
717 aShapeBase = Copy.Shape();
719 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
721 //if for section was specified face with a few wires then a few
722 // pipes were build and make solid
723 if (aTypeBase == TopAbs_SHELL) {
724 // create wire as boundary contour if shell is no closed
725 // get free boundary shapes
726 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
727 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
728 TopExp_Explorer anExp;
730 Standard_Integer NbWires = 0;
731 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
733 aWire = anExp.Current();
737 Standard_ConstructionError::Raise("Bad shell is used as section ");
739 NeedCreateSolid = Standard_True;
740 aSeqFaces.Append(aShapeBase);
741 aSeqBases.Append(aWire);
743 else if (aTypeBase == TopAbs_FACE) {
744 NeedCreateSolid = Standard_True;
745 //for case one path should be used other type function
746 aSeqFaces.Append(aShapeBase);
747 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
748 for (; aExpW.More(); aExpW.Next()) {
749 TopoDS_Shape aWireProf = aExpW.Current();
750 aSeqBases.Append(aWireProf);
753 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
754 aSeqBases.Append(aShapeBase);
756 else if (aTypeBase == TopAbs_EDGE) {
757 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
758 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
759 aSeqBases.Append(aWireProf);
762 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
763 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
765 aSeqLocs.Append(aShapeLoc);
769 nbLocs = aSeqLocs.Length();
772 TopTools_SequenceOfShape Edges;
774 // we have to check that each location shape is a vertex from
775 // path and update aSeqLocs if it is needed (and possible)
776 TColgp_SequenceOfPnt PLocs;
777 for (i=1; i<=nbLocs; i++) {
778 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
779 PLocs.Append(BRep_Tool::Pnt(V));
781 //TopTools_SequenceOfShape Edges;
782 TopExp_Explorer anExp;
783 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
784 Edges.Append(anExp.Current());
786 int nbEdges = Edges.Length();
787 ShapeAnalysis_Edge sae;
788 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
789 double tol = BRep_Tool::Tolerance(edge);
790 TopoDS_Vertex VF = sae.FirstVertex(edge);
791 gp_Pnt PF = BRep_Tool::Pnt(VF);
792 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
793 if (PF.Distance(PLocs.First()) > tol) {
794 Standard_ConstructionError::Raise
795 ("First location shapes is not coincided with first vertex of aWirePath");
797 aSeqLocs.ChangeValue(1) = VF;
798 edge = TopoDS::Edge(Edges.Last());
799 tol = BRep_Tool::Tolerance(edge);
800 TopoDS_Vertex VL = sae.LastVertex(edge);
801 gp_Pnt PL = BRep_Tool::Pnt(VL);
802 if (PL.Distance(PLocs.Last()) > tol) {
803 Standard_ConstructionError::Raise
804 ("Last location shapes is not coincided with last vertex of aWirePath");
806 aSeqLocs.ChangeValue(nbLocs) = VL;
808 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
809 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
810 tol = BRep_Tool::Tolerance(edge);
811 TopoDS_Vertex V1 = sae.FirstVertex(E);
812 TopoDS_Vertex V2 = sae.LastVertex(E);
813 gp_Pnt P1 = BRep_Tool::Pnt(V1);
814 gp_Pnt P2 = BRep_Tool::Pnt(V2);
815 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
816 aSeqLocs.ChangeValue(jcurr) = V2;
820 // find distance between E and aLocs(jcurr)
822 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
823 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
824 if (PPCurve.NbPoints()>0 &&
825 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
826 double param = PPCurve.Parameter(1);
829 // split current edge
830 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
831 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
836 if (Pfp.Distance(P1)<tol) {
837 B.MakeEdge(E1,tc1,tol);
839 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
840 B.Add(E1,TopoDS::Vertex(tmpV));
841 B.MakeEdge(E2,tc2,tol);
842 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
843 B.Add(E2,TopoDS::Vertex(tmpV));
847 B.MakeEdge(E1,tc2,tol);
848 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
849 B.Add(E1,TopoDS::Vertex(tmpV));
852 B.MakeEdge(E2,tc1,tol);
854 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
855 B.Add(E2,TopoDS::Vertex(tmpV));
860 Edges.InsertAfter(i-1,E1);
861 Edges.InsertAfter(i,E2);
865 if (nbEdges<Edges.Length()) {
866 // one of edges was splitted => we have to update WirePath
870 for (i=1; i<=Edges.Length(); i++) {
871 B.Add(W,TopoDS::Edge(Edges.Value(i)));
877 // check curvature of wire for condition that
878 // max summary angle between directions along
879 // wire path must be < 4*PI. If not - split wire
880 // and seguences of shapes, perform pipe for each
881 // and make sewing after that
886 if ( Edges.Length() > 0 ) {
887 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
890 SumAng = fabs(Vec1.Angle(Vec2));
894 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
896 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
897 for (i=2; i<=Edges.Length(); i++) {
898 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
899 double tol = BRep_Tool::Tolerance(edge);
900 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
902 double ang = fabs(Vec1.Angle(Vec2));
906 SplitEdgeNums.Append(i-1);
908 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
909 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
910 gp_Pnt P = BRep_Tool::Pnt(aVert);
911 if (P1.Distance(P) < tol) {
912 SplitLocNums.Append(j);
922 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
923 TopTools_SequenceOfShape aSeqRes;
924 int nn, num1 = 1, num2 = 1;
925 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
926 // create wirepath and sequences of shapes
930 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
931 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
933 num1 = SplitEdgeNums.Value(nn) + 1;
934 TopTools_SequenceOfShape aTmpSeqBases;
935 TopTools_SequenceOfShape aTmpSeqLocs;
936 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
937 aTmpSeqBases.Append(aSeqBases.Value(i));
938 aTmpSeqLocs.Append(aSeqLocs.Value(i));
940 num2 = SplitLocNums.Value(nn);
942 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
943 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
944 if (theBestMode == GeomFill_IsDiscreteTrihedron)
945 aBuilder.SetDiscreteMode();
946 Standard_Integer nbShapes = aTmpSeqBases.Length();
947 for (i=1; i<=nbShapes; i++) {
948 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
949 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
950 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
952 if (!aBuilder.IsReady()) {
953 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
956 BuildPipeShell(aBuilder);
958 TopoDS_Shape resShape = aBuilder.Shape();
959 aSeqRes.Append(resShape);
961 // create wirepath and sequences of shapes for last part
965 for (i=num1; i<=Edges.Length(); i++) {
966 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
968 TopTools_SequenceOfShape aTmpSeqBases;
969 TopTools_SequenceOfShape aTmpSeqLocs;
970 for (i=num2; i<=aSeqLocs.Length(); i++) {
971 aTmpSeqBases.Append(aSeqBases.Value(i));
972 aTmpSeqLocs.Append(aSeqLocs.Value(i));
974 // make pipe for last part
975 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
976 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
977 if (theBestMode == GeomFill_IsDiscreteTrihedron)
978 aBuilder.SetDiscreteMode();
979 Standard_Integer nbShapes = aTmpSeqBases.Length();
980 for (i=1; i<=nbShapes; i++) {
981 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
982 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
983 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
985 if (!aBuilder.IsReady()) {
986 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
989 BuildPipeShell(aBuilder);
991 TopoDS_Shape resShape = aBuilder.Shape();
992 aSeqRes.Append(resShape);
993 // make sewing for result
994 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
995 aSewing->SetTolerance(Precision::Confusion());
996 aSewing->SetFaceMode(Standard_True);
997 aSewing->SetFloatingEdgesMode(Standard_False);
998 aSewing->SetNonManifoldMode(Standard_False);
999 for (i=1; i<=aSeqRes.Length(); i++) {
1000 aSewing->Add(aSeqRes.Value(i));
1003 aShape = aSewing->SewedShape();
1006 // old implementation without splitting
1007 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1008 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1009 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1010 aBuilder.SetDiscreteMode();
1012 Standard_Integer nbShapes = aSeqBases.Length();
1013 Standard_Integer step = nbShapes/nbBases;
1015 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1016 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1018 Standard_Integer ind =0;
1019 Standard_Real aTolConf = Precision::Confusion();
1020 Standard_Real aTolAng = Precision::Angular();
1022 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1023 TopTools_SequenceOfShape usedBases;
1024 Standard_Integer j = 1;
1025 for (; j <= nbBases; j++) {
1026 ind = i + (j-1)*step;
1027 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1028 usedBases.Append(aWireProf);
1030 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1031 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1032 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1035 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1037 if (!aBuilder.IsReady()) {
1038 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1041 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1043 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1045 if (isDone && NeedCreateSolid) {
1046 isDone = aBuilder.MakeSolid();
1050 Standard_ConstructionError::Raise("Pipe construction failure");
1052 aShape = aBuilder.Shape();
1053 aSeqFaces.Append(aShape);
1054 for (j = 1; j <=usedBases.Length(); j++)
1055 aBuilder.Delete(usedBases.Value(j));
1062 //=======================================================================
1063 //function : CreatePipeForShellSections
1064 //purpose : auxilary for Execute()
1065 //=======================================================================
1066 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1067 GEOMImpl_IPipe* aCI)
1069 //cout<<"CreatePipeForShellSections"<<endl;
1074 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1075 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1076 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1077 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1078 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1079 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1081 Standard_Integer nbBases = aBasesObjs->Length(),
1082 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1083 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1085 if (nbLocs != nbBases) {
1086 if (aCI) delete aCI;
1087 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1089 if (nbSubBases && nbSubBases != nbBases) {
1090 if (aCI) delete aCI;
1091 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1094 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1096 TopTools_SequenceOfShape VLocs;
1097 for (i=1; i<=nbBases; i++) {
1098 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1099 if (anItemLoc.IsNull())
1101 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1102 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1103 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1105 VLocs.Append(aShapeLoc);
1107 nbLocs = VLocs.Length();
1108 if (nbLocs != nbBases) {
1109 if (aCI) delete aCI;
1110 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1112 // split wire path by location points
1113 TColgp_SequenceOfPnt PLocs;
1114 for (i=1; i<=nbLocs; i++) {
1115 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1116 PLocs.Append(BRep_Tool::Pnt(V));
1119 TopTools_SequenceOfShape Edges;
1120 TopTools_SequenceOfShape Wires;
1121 ShapeAnalysis_Edge sae;
1124 TopExp_Explorer anExp;
1125 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1126 Edges.Append(anExp.Current());
1128 Standard_Integer Num1 = 0;
1129 Standard_Integer Num2 = 0;
1130 for (i=1; i<=Edges.Length(); i++) {
1131 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1132 double tol = BRep_Tool::Tolerance(E);
1133 TopoDS_Vertex V1 = sae.FirstVertex(E);
1134 TopoDS_Vertex V2 = sae.LastVertex(E);
1135 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1136 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1137 if (P1.Distance(PLocs.First()) < tol) {
1140 if (P2.Distance(PLocs.Last()) < tol) {
1144 if (Num1>0 && Num2>0) {
1147 for (i=Num1; i<=Num2; i++) {
1148 B.Add(W,Edges.Value(i));
1153 Wires.Append(aWirePath);
1157 TopExp_Explorer anExp;
1158 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1159 Edges.Append(anExp.Current());
1161 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1162 double tol = BRep_Tool::Tolerance(edge);
1163 TopoDS_Vertex VF = sae.FirstVertex(edge);
1164 gp_Pnt PF = BRep_Tool::Pnt(VF);
1165 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1166 if (PF.Distance(PLocs.First()) > tol) {
1167 if (aCI) delete aCI;
1168 Standard_ConstructionError::Raise
1169 ("First location shapes is not coincided with first vertex of aWirePath");
1171 VLocs.ChangeValue(1) = VF;
1172 edge = TopoDS::Edge(Edges.Last());
1173 tol = BRep_Tool::Tolerance(edge);
1174 TopoDS_Vertex VL = sae.LastVertex(edge);
1175 gp_Pnt PL = BRep_Tool::Pnt(VL);
1176 if (PL.Distance(PLocs.Last()) > tol) {
1177 if (aCI) delete aCI;
1178 Standard_ConstructionError::Raise
1179 ("Last location shapes is not coincided with last vertex of aWirePath");
1181 VLocs.ChangeValue(nbLocs) = VL;
1183 TopTools_SequenceOfShape tmpEdges;
1184 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1185 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1186 tol = BRep_Tool::Tolerance(E);
1187 TopoDS_Vertex V1 = sae.FirstVertex(E);
1188 TopoDS_Vertex V2 = sae.LastVertex(E);
1189 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1190 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1191 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1192 // make wire from current edge and add created
1196 for (j=1; j<=tmpEdges.Length(); j++)
1197 B.Add(W,tmpEdges.Value(j));
1200 VLocs.ChangeValue(jcurr) = V2;
1205 // find distance between E and aLocs(jcurr)
1207 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1208 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1209 if (PPCurve.NbPoints()>0 &&
1210 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1211 double param = PPCurve.Parameter(1);
1214 // split current edge
1215 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1216 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1220 if (Pfp.Distance(P1)<tol) {
1221 B.MakeEdge(E1,tc1,tol);
1223 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1224 B.Add(E1,TopoDS::Vertex(tmpV));
1225 tmpEdges.Append(E1);
1226 B.MakeEdge(E2,tc2,tol);
1227 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1228 B.Add(E2,TopoDS::Vertex(tmpV));
1232 B.MakeEdge(E1,tc2,tol);
1233 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1234 B.Add(E1,TopoDS::Vertex(tmpV));
1237 tmpEdges.Append(E1);
1238 B.MakeEdge(E2,tc1,tol);
1240 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1241 B.Add(E2,TopoDS::Vertex(tmpV));
1244 // create wire from tmpEdges
1247 for (j=1; j<=tmpEdges.Length(); j++)
1248 B.Add(W,tmpEdges.Value(j));
1253 Edges.InsertAfter(i-1,E1);
1254 Edges.InsertAfter(i,E2);
1261 // create wire from other edges
1264 for (; i<=Edges.Length(); i++)
1265 B.Add(W,Edges.Value(i));
1267 //cout<<"Wires.Length()="<<Wires.Length()<<endl;
1270 if (Wires.Length() != nbLocs-1) {
1271 if (aCI) delete aCI;
1272 Standard_ConstructionError::Raise
1273 ("One of location shapes is not lied on the path");
1276 //TopTools_SequenceOfShape aSeqBases;
1277 //TopTools_SequenceOfShape aSeqSubBases;
1278 //TopTools_SequenceOfShape aSeqFaces;
1279 TopoDS_Compound aComp;
1280 B.MakeCompound(aComp);
1281 for (i = 1; i < nbBases; i++) {
1282 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1284 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1285 if (anItem1.IsNull())
1287 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1288 if (aRefBase1.IsNull())
1290 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1291 if (aShBase1.IsNull())
1293 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1295 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1296 if (anItem2.IsNull())
1298 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1299 if (aRefBase2.IsNull())
1301 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1302 if (aShBase2.IsNull())
1304 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1306 //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
1308 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1309 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1311 if (aCI) delete aCI;
1312 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1315 bool CreateFewSolids = false;
1317 TopExp_Explorer anExp;
1318 Standard_Integer nbf1 = 0;
1319 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1322 Standard_Integer nbf2 = 0;
1323 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1327 CreateFewSolids = true;
1331 // check orientation of sections
1332 bool NeedReverse = false;
1335 anExp.Init(aShBase1, TopAbs_FACE);
1336 TopoDS_Shape aFace = anExp.Current();
1337 TColgp_SequenceOfPnt aPnts;
1338 double xc=0, yc=0, zc=0;
1339 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1340 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1341 aPnts.Append(BRep_Tool::Pnt(V));
1342 xc += aPnts.Last().X();
1343 yc += aPnts.Last().Y();
1344 zc += aPnts.Last().Z();
1346 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1347 gp_Vec V1(PC,aPnts.Value(1));
1348 gp_Vec V2(PC,aPnts.Value(2));
1349 gp_Vec VN = V1.Crossed(V2);
1350 for (int ip=2; ip<aPnts.Length(); ip++) {
1351 V1 = gp_Vec(PC,aPnts.Value(ip));
1352 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1353 VN.Add(V1.Crossed(V2));
1356 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
1358 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1359 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1360 double tol = BRep_Tool::Tolerance(edge);
1361 TopoDS_Vertex VF = sae.FirstVertex(edge);
1362 gp_Pnt PF = BRep_Tool::Pnt(VF);
1363 if (PF.Distance(PLoc) < tol) {
1365 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1368 if (P1.Distance(PLoc) < tol) {
1369 C->D0(fp+(lp-fp)/100,P2);
1373 C->D0(lp+(fp-lp)/100,P2);
1375 PathNorm = gp_Vec(P1,P2);
1379 TopoDS_Vertex VL = sae.LastVertex(edge);
1380 gp_Pnt PL = BRep_Tool::Pnt(VL);
1381 if (PL.Distance(PLoc) < tol) {
1383 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1386 if (P1.Distance(PLoc) < tol) {
1387 C->D0(fp+(lp-fp)/100,P2);
1391 C->D0(lp+(fp-lp)/100,P2);
1393 PathNorm = gp_Vec(P2,P1);
1398 cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1399 cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1400 if (fabs(VN.Angle(PathNorm))>PI/2.) {
1407 anExp.Init(aShBase2, TopAbs_FACE);
1408 TopoDS_Shape aFace = anExp.Current();
1409 TColgp_SequenceOfPnt aPnts;
1410 double xc=0, yc=0, zc=0;
1411 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1412 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1413 aPnts.Append(BRep_Tool::Pnt(V));
1414 xc += aPnts.Last().X();
1415 yc += aPnts.Last().Y();
1416 zc += aPnts.Last().Z();
1418 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1419 gp_Vec V1(PC,aPnts.Value(1));
1420 gp_Vec V2(PC,aPnts.Value(2));
1421 gp_Vec VN = V1.Crossed(V2);
1422 for (int ip=2; ip<aPnts.Length(); ip++) {
1423 V1 = gp_Vec(PC,aPnts.Value(ip));
1424 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1425 VN.Add(V1.Crossed(V2));
1428 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
1430 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1431 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1432 double tol = BRep_Tool::Tolerance(edge);
1433 TopoDS_Vertex VF = sae.FirstVertex(edge);
1434 gp_Pnt PF = BRep_Tool::Pnt(VF);
1435 if (PF.Distance(PLoc) < tol) {
1437 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1440 if (P1.Distance(PLoc) < tol) {
1441 C->D0(fp+(lp-fp)/100,P2);
1445 C->D0(lp+(fp-lp)/100,P2);
1447 PathNorm = gp_Vec(P2,P1);
1451 TopoDS_Vertex VL = sae.LastVertex(edge);
1452 gp_Pnt PL = BRep_Tool::Pnt(VL);
1453 if (PL.Distance(PLoc) < tol) {
1455 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1458 if (P1.Distance(PLoc) < tol) {
1459 C->D0(fp+(lp-fp)/100,P2);
1463 C->D0(lp+(fp-lp)/100,P2);
1465 PathNorm = gp_Vec(P2,P1);
1470 //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1471 //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1472 if (fabs(VN.Angle(PathNorm))>PI/2.)
1477 if (!CreateFewSolids) {
1478 // we can create only one solid
1479 TopoDS_Shape aWire1, aWire2;
1481 if (aType1==TopAbs_SHELL) {
1482 // create wire as boundary contour if shell is no closed
1483 // get free boundary shapes
1484 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1485 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1486 //TopExp_Explorer anExp;
1487 Standard_Integer NbWires = 0;
1488 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1490 aWire1 = anExp.Current();
1494 if (aCI) delete aCI;
1495 Standard_ConstructionError::Raise("Bad shell is used as section ");
1498 else { // aType1==TopAbs_FACE
1499 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1500 aWire1 = aExpW.Current();
1503 if (aType2==TopAbs_SHELL) {
1504 // create wire as boundary contour if shell is no closed
1505 // get free boundary shapes
1506 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1507 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1508 //TopExp_Explorer anExp;
1509 Standard_Integer NbWires = 0;
1510 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1512 aWire2 = anExp.Current();
1516 if (aCI) delete aCI;
1517 Standard_ConstructionError::Raise("Bad shell is used as section ");
1520 else { // aType2==TopAbs_FACE
1521 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1522 aWire2 = aExpW.Current();
1524 // make pipe using aWire1 and aWire2
1525 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1526 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1527 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1528 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1529 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1530 aBuilder.SetDiscreteMode();
1531 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1532 aWithContact, aWithCorrect);
1533 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1534 aWithContact, aWithCorrect);
1535 if (!aBuilder.IsReady()) {
1536 if (aCI) delete aCI;
1537 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1540 BuildPipeShell(aBuilder);
1542 TopoDS_Shape aShape = aBuilder.Shape();
1543 TopoDS_Shell aShell;
1544 B.MakeShell(aShell);
1545 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1546 B.Add(aShell,anExp.Current());
1548 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1549 B.Add(aShell,anExp.Current());
1551 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1552 B.Add(aShell,anExp.Current());
1554 // make sewing for this shell
1555 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1556 aSewing->SetTolerance(Precision::Confusion());
1557 aSewing->SetFaceMode(Standard_True);
1558 aSewing->SetFloatingEdgesMode(Standard_False);
1559 aSewing->SetNonManifoldMode(Standard_False);
1560 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1561 aSewing->Add(anExp.Current());
1564 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1565 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1566 aShell = TopoDS::Shell(aSewShape);
1567 GProp_GProps aSystem;
1568 BRepGProp::VolumeProperties(aShell, aSystem);
1569 if (aSystem.Mass()<0) {
1572 if (BRep_Tool::IsClosed(aShell)) {
1573 TopoDS_Solid aSolid;
1574 B.MakeSolid(aSolid);
1575 B.Add(aSolid,aShell);
1576 B.Add(aComp,aSolid);
1579 B.Add(aComp,aShell);
1583 B.Add(aComp,aShell);
1588 // main block - creation few solids (for each pair of faces)
1589 TopTools_MapOfShape aFaces1,aFaces2;
1590 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1591 aFaces1.Add(anExp.Current());
1593 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1594 aFaces2.Add(anExp.Current());
1596 // creating map of edge faces
1597 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1598 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1599 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1600 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1602 // constuct map face->face
1603 TopTools_IndexedDataMapOfShapeShape FF;
1604 TopoDS_Shape FS1,FS2;
1605 if (nbSubBases==0) {
1606 // find edge the most distant from location point
1607 // (this edge is not shared by two faces)
1608 double maxdist = 0.;
1610 TopoDS_Vertex V11,V21;
1611 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1612 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1613 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1614 if (aList.Extent()>1)
1616 TopExp_Explorer expv;
1617 expv.Init(tmp, TopAbs_VERTEX);
1618 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1620 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1621 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1622 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1623 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1628 TopTools_ListIteratorOfListOfShape anIter(aList);
1629 FS1 = anIter.Value();
1633 // main direction for comparing
1634 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1635 // find corresponding edge from next section
1636 double minang = M_PI;
1637 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1638 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1640 TopoDS_Vertex V12,V22;
1641 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1642 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1643 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1644 if (aList.Extent()>1)
1646 TopExp_Explorer expv;
1647 expv.Init(tmp, TopAbs_VERTEX);
1648 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1650 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1651 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1652 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1653 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1654 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1655 TopoDS_Vertex V1,V2;
1658 V1 = V2tmp; P1 = P2tmp;
1659 V2 = V1tmp; P2 = P1tmp;
1662 V1 = V1tmp; P1 = P1tmp;
1663 V2 = V2tmp; P2 = P2tmp;
1665 gp_Vec Vec1(P11,P1);
1666 gp_Vec Vec2(P21,P2);
1667 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1672 TopTools_ListIteratorOfListOfShape anIter(aList);
1673 FS2 = anIter.Value();
1677 // put all pairs to map FF
1683 // add pairs of edges to FF
1684 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1686 if (aCI) delete aCI;
1687 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1693 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1694 if (anItem.IsNull()) {
1695 if (aCI) delete aCI;
1696 Standard_ConstructionError::Raise("Invalid subbase shape");
1698 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1699 if (aRefBase.IsNull()) {
1700 if (aCI) delete aCI;
1701 Standard_ConstructionError::Raise("Invalid subbase shape");
1703 TopoDS_Shape aSh = aRefBase->GetValue();
1705 if (aCI) delete aCI;
1706 Standard_ConstructionError::Raise("Invalid subbase shape");
1708 if (aSh.ShapeType()!=TopAbs_FACE) {
1709 if (aCI) delete aCI;
1710 Standard_ConstructionError::Raise("Invalid subbase shape");
1715 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1716 if (anItem.IsNull()) {
1717 if (aCI) delete aCI;
1718 Standard_ConstructionError::Raise("Invalid subbase shape");
1720 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1721 if (aRefBase.IsNull()) {
1722 if (aCI) delete aCI;
1723 Standard_ConstructionError::Raise("Invalid subbase shape");
1725 TopoDS_Shape aSh = aRefBase->GetValue();
1727 if (aCI) delete aCI;
1728 Standard_ConstructionError::Raise("Invalid subbase shape");
1730 if (aSh.ShapeType()!=TopAbs_FACE) {
1731 if (aCI) delete aCI;
1732 Standard_ConstructionError::Raise("Invalid subbase shape");
1737 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1738 if (aCI) delete aCI;
1739 Standard_ConstructionError::Raise("Invalid subbase shape");
1744 // add pairs of edges to FF
1745 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1746 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1748 if (aCI) delete aCI;
1749 Standard_ConstructionError::Raise("Can not create correct pipe");
1753 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1755 // make pipe for each pair of faces
1756 for (j=1; j<=FF.Extent(); j++) {
1757 TopoDS_Shape F1 = FF.FindKey(j);
1758 if (F1.ShapeType() != TopAbs_FACE)
1760 TopoDS_Shape F2 = FF.FindFromIndex(j);
1761 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1762 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1763 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1764 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1765 // make pipe using aWire1 and aWire2
1766 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1767 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1768 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1769 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1770 aBuilder.SetDiscreteMode();
1771 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1772 aWithContact, aWithCorrect);
1773 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1774 aWithContact, aWithCorrect);
1775 if (!aBuilder.IsReady()) {
1776 if (aCI) delete aCI;
1777 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1780 BuildPipeShell(aBuilder);
1782 TopoDS_Shape aShape = aBuilder.Shape();
1783 TopoDS_Shell aShell;
1784 B.MakeShell(aShell);
1785 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1786 B.Add(aShell,anExp.Current());
1791 // make sewing for this shell
1792 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1793 aSewing->SetTolerance(Precision::Confusion());
1794 aSewing->SetFaceMode(Standard_True);
1795 aSewing->SetFloatingEdgesMode(Standard_False);
1796 aSewing->SetNonManifoldMode(Standard_False);
1797 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1798 aSewing->Add(anExp.Current());
1801 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1802 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1803 aShell = TopoDS::Shell(aSewShape);
1804 GProp_GProps aSystem;
1805 BRepGProp::VolumeProperties(aShell, aSystem);
1806 if (aSystem.Mass()<0) {
1807 //cout<<"aSewShape is reversed"<<endl;
1810 if (BRep_Tool::IsClosed(aShell)) {
1811 TopoDS_Solid aSolid;
1812 B.MakeSolid(aSolid);
1813 B.Add(aSolid,aShell);
1814 B.Add(aComp,aSolid);
1817 B.Add(aComp,aShell);
1821 B.Add(aComp,aShell);
1829 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
1833 //=======================================================================
1834 //function : CreatePipeShellsWithoutPath
1835 //purpose : auxilary for Execute()
1836 //=======================================================================
1837 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
1839 //cout<<"CreatePipeShellsWithoutPath"<<endl;
1843 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1845 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1846 // vertex for recognition
1847 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
1849 Standard_Integer nbBases = aBasesObjs->Length(),
1850 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
1852 if (nbv != nbBases) {
1853 if (aCI) delete aCI;
1854 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
1857 TopTools_SequenceOfShape SecVs,Bases;
1858 for (i=1; i<=nbBases; i++) {
1860 Handle(Standard_Transient) anItem = VObjs->Value(i);
1861 if (anItem.IsNull())
1863 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
1864 TopoDS_Shape V = aRef->GetValue();
1865 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
1869 anItem = aBasesObjs->Value(i);
1870 if (anItem.IsNull())
1872 aRef = Handle(GEOM_Function)::DownCast(anItem);
1873 TopoDS_Shape aSh = aRef->GetValue();
1878 nbv = SecVs.Length();
1879 nbBases = Bases.Length();
1880 if (nbv != nbBases) {
1881 if (aCI) delete aCI;
1882 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
1885 TopoDS_Compound aComp;
1886 B.MakeCompound(aComp);
1888 for (i = 1; i < nbBases; i++) {
1889 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
1890 TopoDS_Shape aShBase1 = Bases.Value(i);
1891 TopoDS_Shape aShBase2 = Bases.Value(i+1);
1892 TopExp_Explorer anExp;
1893 Standard_Integer nbf1 = 0;
1894 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1897 Standard_Integer nbf2 = 0;
1898 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1901 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
1903 if (aCI) delete aCI;
1904 Standard_ConstructionError::Raise("Different number of faces in the sections");
1907 TopTools_MapOfShape aFaces1,aFaces2;
1908 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1909 aFaces1.Add(anExp.Current());
1911 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1912 aFaces2.Add(anExp.Current());
1915 // creating map of edge faces
1916 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1917 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1918 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1919 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1921 // constuct map face->face (and sub-shapes)
1922 TopTools_IndexedDataMapOfShapeShape FF;
1923 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
1924 TopoDS_Shape FS1, FS2;
1925 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
1926 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
1927 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
1930 MESSAGE (" first pair of corresponding faces is found");
1932 // add pairs of edges and vertexes to FF
1933 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
1935 if (aCI) delete aCI;
1936 Standard_ConstructionError::Raise("Can not create correct pipe");
1938 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
1940 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1941 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
1943 // make pipe for each pair of faces
1944 // auxilary map vertex->edge for created pipe edges
1945 TopTools_IndexedDataMapOfShapeShape VPE;
1946 ShapeAnalysis_Edge sae;
1947 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
1949 for (j=1; j<=FF.Extent(); j++) {
1950 TopoDS_Shape F1 = FF.FindKey(j);
1951 if (F1.ShapeType() != TopAbs_FACE)
1953 TopoDS_Shape F2 = FF.FindFromIndex(j);
1956 //if (nbff!=3) continue;
1958 MESSAGE (" make pipe for "<<nbff<<" face");
1960 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
1961 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1962 Handle(Geom_RectangularTrimmedSurface) RTS =
1963 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
1964 S1 = RTS->BasisSurface();
1966 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
1967 if (Pln1.IsNull()) {
1968 if (aCI) delete aCI;
1969 Standard_ConstructionError::Raise("Surface from face is not plane");
1971 gp_Vec aDir1(Pln1->Axis().Direction());
1973 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
1974 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1975 Handle(Geom_RectangularTrimmedSurface) RTS =
1976 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
1977 S2 = RTS->BasisSurface();
1979 Handle(Geom_Plane) Pln2 =
1980 Handle(Geom_Plane)::DownCast(S2);
1981 if (Pln2.IsNull()) {
1982 if (aCI) delete aCI;
1983 Standard_ConstructionError::Raise("Surface from face is not plane");
1985 gp_Vec aDir2(Pln2->Axis().Direction());
1987 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
1988 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
1990 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
1992 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
1995 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
1996 TopTools_SequenceOfShape aNewFs;
1998 for (; anExpE.More(); anExpE.Next()) {
1999 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2001 if (!FF.Contains(E1))
2002 MESSAGE ("map FF not contains key E1");
2004 if (VPE.Contains(E1)) {
2005 aNewFs.Append(VPE.FindFromKey(E1));
2007 MESSAGE (" using existed face");
2012 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2013 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2014 TopoDS_Vertex V2 = sae.LastVertex(E1);
2015 if (!FF.Contains(V1))
2016 MESSAGE ("map FF not contains key V1");
2017 if (!FF.Contains(V2))
2018 MESSAGE ("map FF not contains key V2");
2019 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2020 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2021 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2022 if (Vtmp.IsSame(V4))
2024 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2025 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2026 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2027 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2030 Handle(Geom_BSplineCurve) C2;
2031 if (VPE.Contains(V2)) {
2032 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2034 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2037 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2038 HAP->SetValue(1,P2);
2039 HAP->SetValue(2,P3);
2040 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2041 anInt.Load(aDir1,aDir2);
2044 B.MakeEdge(E2,C2,1.e-7);
2045 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2046 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2051 Handle(Geom_BSplineCurve) C4;
2052 if (VPE.Contains(V1)) {
2053 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2055 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2058 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2059 HAP->SetValue(1,P1);
2060 HAP->SetValue(2,P4);
2061 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2062 anInt.Load(aDir1,aDir2);
2065 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2066 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2067 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2076 B.Add(W,E4.Reversed());
2077 //cout<<" wire for edge "<<nbee<<" is created"<<endl;
2078 //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
2083 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2084 //bool IsConicC1 = false;
2085 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2086 // IsConicC1 = true;
2087 // cout<<"C1 - Geom_Conic"<<endl;
2089 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2090 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2093 // double tol = BRep_Tool::Tolerance(E1);
2094 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2095 // C1 = ApxC1.Curve();
2097 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2098 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2099 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2104 Handle(Geom_BSplineCurve) CE1 =
2105 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2106 if (CE1->Degree()<3)
2107 CE1->IncreaseDegree(3);
2108 Handle(Geom_BSplineCurve) CE2 =
2109 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2110 if (CE2->Degree()<3)
2111 CE2->IncreaseDegree(3);
2112 Handle(Geom_BSplineCurve) CE3 =
2113 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2114 if (CE3->Degree()<3)
2115 CE3->IncreaseDegree(3);
2116 Handle(Geom_BSplineCurve) CE4 =
2117 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2118 if (CE4->Degree()<3)
2119 CE4->IncreaseDegree(3);
2120 //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
2121 // <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
2122 //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
2123 // os<<"DrawTrSurf_BSplineCurve"<<endl;
2124 // GeomTools::Write(CE1,os);
2128 Handle(Geom_Surface) BS;
2130 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2131 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2135 MESSAGE (" can not create BSplineSurface - create Bezier");
2137 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2138 double fp1,lp1,fp2,lp2;
2139 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2140 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2149 // get points from C1
2150 if (P1.Distance(P1C1)<1.e-6) {
2158 double step = (lp-fp)/(NbP-1);
2159 Points.SetValue(1,1,P1);
2161 for (n1=2; n1<NbP; n1++) {
2165 Points.SetValue(1,n1,P);
2167 Points.SetValue(1,NbP,P2);
2168 // get points from C3
2169 if (P4.Distance(P1C3)<1.e-6) {
2177 step = (lp-fp)/(NbP-1);
2178 Points.SetValue(NbP,1,P4);
2180 for (n1=2; n1<NbP; n1++) {
2184 Points.SetValue(NbP,n1,P);
2186 Points.SetValue(NbP,NbP,P3);
2187 // create isolines and get points from them
2188 for (n1=1; n1<=NbP; n1++) {
2189 gp_Pnt PI1 = Points.Value(1,n1);
2190 gp_Pnt PI2 = Points.Value(NbP,n1);
2191 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2192 HAP->SetValue(1,PI1);
2193 HAP->SetValue(2,PI2);
2194 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2195 anInt.Load(aDir1,aDir2);
2197 Handle(Geom_Curve) iso = anInt.Curve();
2198 fp = iso->FirstParameter();
2199 lp = iso->LastParameter();
2200 step = (lp-fp)/(NbP-1);
2202 TopoDS_Compound VComp;
2203 B.MakeCompound(VComp);
2204 for (n2=2; n2<NbP; n2++) {
2208 Points.SetValue(n2,n1,P);
2211 // create surface and face
2212 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2213 BS = new Geom_BezierSurface(Points);
2216 BRepBuilderAPI_MakeFace BB(BS,W);
2217 TopoDS_Face NewF = BB.Face();
2218 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2220 sff->FixOrientation();
2221 TopoDS_Face FixedFace = sff->Face();
2222 aNewFs.Append(FixedFace);
2223 VPE.Add(E1,FixedFace);
2224 //cout<<" face for edge "<<nbee<<" is created"<<endl;
2225 //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
2228 TopoDS_Shell aShell;
2229 B.MakeShell(aShell);
2230 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2231 B.Add(aShell,aNewFs(nf));
2236 // make sewing for this shell
2237 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2238 aSewing->SetTolerance(Precision::Confusion());
2239 aSewing->SetFaceMode(Standard_True);
2240 aSewing->SetFloatingEdgesMode(Standard_False);
2241 aSewing->SetNonManifoldMode(Standard_False);
2242 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2243 aSewing->Add(anExp.Current());
2246 MESSAGE (" shell for face "<<nbff<<" is created");
2247 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2248 //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
2249 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2250 aShell = TopoDS::Shell(aSewShape);
2251 GProp_GProps aSystem;
2252 BRepGProp::VolumeProperties(aShell, aSystem);
2253 if (aSystem.Mass()<0) {
2254 //cout<<"aSewShape is reversed"<<endl;
2257 if (BRep_Tool::IsClosed(aShell)) {
2258 TopoDS_Solid aSolid;
2259 B.MakeSolid(aSolid);
2260 B.Add(aSolid,aShell);
2261 B.Add(aComp,aSolid);
2262 MESSAGE (" solid for face "<<nbff<<" is created");
2265 B.Add(aComp,aShell);
2266 MESSAGE (" solid for face "<<nbff<<" is not created");
2270 B.Add(aComp,aShell);
2271 MESSAGE (" solid for face "<<nbff<<" is not created");
2273 //cout<<" solid for face "<<nbff<<" is created"<<endl;
2275 //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
2277 //TopoDS_Shell FixedShell = sfs->Shell();
2279 GProp_GProps aSystem;
2280 BRepGProp::VolumeProperties(FixedShell, aSystem);
2281 if (aSystem.Mass()<0) {
2282 //cout<<"aSewShape is reversed"<<endl;
2283 FixedShell.Reverse();
2285 if (BRep_Tool::IsClosed(FixedShell)) {
2286 TopoDS_Solid aSolid;
2287 B.MakeSolid(aSolid);
2288 B.Add(aSolid,aShell);
2289 B.Add(aComp,aSolid);
2292 B.Add(aComp,FixedShell);
2298 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
2302 //=======================================================================
2303 //function : CreatePipeBiNormalAlongVector
2304 //purpose : auxilary for Execute()
2305 //=======================================================================
2306 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2307 GEOMImpl_IPipe* aCI)
2309 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2311 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2312 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2313 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2314 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2316 if (aShapeBase.IsNull()) {
2317 if (aCIBN) delete aCIBN;
2318 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2321 // Make copy to prevent modifying of base object: 0021525
2322 BRepBuilderAPI_Copy Copy (aShapeBase);
2324 aShapeBase = Copy.Shape();
2327 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2330 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2331 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2333 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2336 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2337 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2338 aProf = wexp.Current();
2341 Standard_TypeMismatch::Raise
2342 ("MakePipe aborted : invalid type of base");
2344 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2345 PipeBuilder.Add(aProf);
2347 if (aShapeVec.IsNull()) {
2348 if (aCIBN) delete aCIBN;
2349 Standard_NullObject::Raise
2350 ("MakePipe aborted : null vector argument");
2352 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2353 Standard_TypeMismatch::Raise
2354 ("MakePipe aborted: invalid type of vector");
2355 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2356 TopoDS_Vertex V1, V2;
2357 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2358 if (V1.IsNull() || V2.IsNull())
2359 Standard_NullObject::Raise
2360 ("MakePipe aborted: vector is not defined");
2361 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2362 gp_Dir BiNormal(aVec);
2363 PipeBuilder.SetMode(BiNormal);
2365 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2367 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2368 PipeBuilder.MakeSolid();
2371 return PipeBuilder.Shape();
2374 //=======================================================================
2375 //function : Execute
2377 //=======================================================================
2378 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
2380 if (Label().IsNull()) return 0;
2381 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
2382 Standard_Integer aType = aFunction->GetType();
2384 GEOMImpl_IPipe* aCI = 0;
2385 if (aType == PIPE_BASE_PATH)
2386 aCI = new GEOMImpl_IPipe (aFunction);
2387 else if (aType == PIPE_DIFFERENT_SECTIONS)
2388 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
2389 else if (aType == PIPE_SHELL_SECTIONS)
2390 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2391 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
2392 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2393 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
2394 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
2398 TopoDS_Wire aWirePath;
2399 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
2400 // working with path
2401 Handle(GEOM_Function) aRefPath = aCI->GetPath();
2402 TopoDS_Shape aShapePath = aRefPath->GetValue();
2404 if (aShapePath.IsNull()) {
2405 MESSAGE ("Driver : path is null");
2406 if (aCI) delete aCI;
2407 Standard_NullObject::Raise("MakePipe aborted : null path argument");
2412 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
2413 TopTools_SequenceOfShape anEdges;
2414 TopExp_Explorer anExp;
2418 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2419 B.Add(W, anExp.Current());
2425 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
2426 aWirePath = TopoDS::Wire(aShapePath);
2430 if (aShapePath.ShapeType() == TopAbs_EDGE) {
2431 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
2432 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
2437 if (aCI) delete aCI;
2438 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
2442 TopoDS_Shape aShape;
2444 if (aType == PIPE_BASE_PATH) {
2445 Handle(GEOM_Function) aRefBase = aCI->GetBase();
2446 TopoDS_Shape aShapeBase;
2448 // Make copy to prevent modifying of base object 0020766 : EDF 1320
2449 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
2451 aShapeBase = Copy.Shape();
2453 if (aShapeBase.IsNull()) {
2454 if (aCI) delete aCI;
2455 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2459 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
2460 aShapeBase.ShapeType() == TopAbs_WIRE)
2462 TopoDS_Wire Profile;
2463 if (aShapeBase.ShapeType() == TopAbs_WIRE)
2464 Profile = TopoDS::Wire(aShapeBase);
2468 BB.MakeWire(Profile);
2469 BB.Add(Profile, aShapeBase);
2472 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
2473 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
2474 if (FaceBuilder.IsDone())
2475 Sweep.SetMode(FaceBuilder.Face());
2478 Standard_Boolean isDone = BuildPipeShell(Sweep);
2482 if (aCI) delete aCI;
2483 Standard_ConstructionError::Raise("MakePipeShell failed");
2486 aShape = Sweep.Shape(); //result is good
2491 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
2492 BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode);
2494 if (aMkPipe.IsDone()) {
2495 aShape = aMkPipe.Shape();
2496 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
2497 // Try to use Descrete Trihedron mode.
2498 BRepOffsetAPI_MakePipe aMkPipeDescrete
2499 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron);
2501 if (aMkPipeDescrete.IsDone()) {
2502 aShape = aMkPipeDescrete.Shape();
2508 //building pipe with different sections
2509 else if (aType == PIPE_DIFFERENT_SECTIONS) {
2510 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
2511 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
2512 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
2513 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
2514 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
2520 Standard_Integer nbBases = aBasesObjs->Length();
2521 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
2523 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
2524 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
2527 for (i = 1; i <= nbBases; i++) {
2528 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
2529 if (anItem.IsNull())
2531 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
2532 if (aRefBase.IsNull())
2534 if (aRefBase->GetValue().IsNull())
2537 aHSeqBases->Append(aRefBase->GetValue());
2539 for (i = 1; i <= nbLocs; i++) {
2540 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
2541 if (anItemLoc.IsNull())
2543 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
2544 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
2545 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
2548 aHSeqLocs->Append(aShapeLoc);
2551 aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
2554 //building pipe with shell sections
2555 else if (aType == PIPE_SHELL_SECTIONS) {
2556 aShape = CreatePipeForShellSections(aWirePath,aCI);
2559 //building pipe shell sections without path
2560 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
2561 aShape = CreatePipeShellsWithoutPath(aCI);
2564 //building a pipe with constant bi-normal along given vector
2565 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
2566 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
2574 if (aShape.IsNull()) return 0;
2576 BRepCheck_Analyzer ana (aShape, Standard_False);
2577 if (!ana.IsValid()) {
2578 ShapeFix_ShapeTolerance aSFT;
2579 aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
2580 Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
2581 aSfs->SetPrecision(Precision::Confusion());
2583 aShape = aSfs->Shape();
2585 ana.Init(aShape, Standard_False);
2587 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
2590 if (aType != PIPE_BASE_PATH &&
2591 aType != PIPE_SHELLS_WITHOUT_PATH) {
2592 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
2593 if (anExpV.More()) {
2594 Standard_Real aVertMaxTol = -RealLast();
2595 for (; anExpV.More(); anExpV.Next()) {
2596 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
2597 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
2598 if (aTol > aVertMaxTol)
2601 aVertMaxTol += Precision::Confusion();
2602 aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
2603 //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
2607 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
2608 aFunction->SetValue(aRes);
2610 log.SetTouched(Label());
2614 //================================================================================
2616 * \brief Returns a name of creation operation and names and values of creation parameters
2618 //================================================================================
2620 bool GEOMImpl_PipeDriver::
2621 GetCreationInformation(std::string& theOperationName,
2622 std::vector<GEOM_Param>& theParams)
2624 if (Label().IsNull()) return 0;
2625 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
2626 Standard_Integer aType = function->GetType();
2629 case PIPE_BASE_PATH:
2631 theOperationName = "PIPE";
2632 GEOMImpl_IPipe aCI( function );
2633 AddParam( theParams, "Base Object", aCI.GetBase() );
2634 AddParam( theParams, "Path Object", aCI.GetPath() );
2637 case PIPE_BI_NORMAL_ALONG_VECTOR:
2639 theOperationName = "PIPE";
2640 GEOMImpl_IPipeBiNormal aCI( function );
2641 AddParam( theParams, "Base Object", aCI.GetBase() );
2642 AddParam( theParams, "Path Object", aCI.GetPath() );
2643 AddParam( theParams, "BiNormal", aCI.GetVector() );
2646 case PIPE_DIFFERENT_SECTIONS:
2648 theOperationName = "PIPE";
2649 GEOMImpl_IPipeDiffSect aCI( function );
2650 AddParam( theParams, "Bases", aCI.GetBases() );
2651 AddParam( theParams, "Locations", aCI.GetLocations() );
2652 AddParam( theParams, "Path", aCI.GetPath() );
2653 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
2654 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
2657 case PIPE_SHELL_SECTIONS:
2659 theOperationName = "PIPE";
2660 GEOMImpl_IPipeShellSect aCI( function );
2661 AddParam( theParams, "Bases", aCI.GetBases() );
2662 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
2663 AddParam( theParams, "Locations", aCI.GetLocations() );
2664 AddParam( theParams, "Path", aCI.GetPath() );
2665 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
2666 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
2669 case PIPE_SHELLS_WITHOUT_PATH:
2671 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
2672 GEOMImpl_IPipeShellSect aCI( function );
2673 AddParam( theParams, "Bases", aCI.GetBases() );
2674 AddParam( theParams, "Locations", aCI.GetLocations() );
2684 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
2685 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);