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)
156 //=======================================================================
157 //function : FillForOtherEdges
158 //purpose : auxilary for CreatePipeForShellSections()
159 //=======================================================================
160 static bool FillForOtherEdges(const TopoDS_Shape& F1,
161 const TopoDS_Shape& E1,
162 const TopoDS_Shape& V1,
163 TopTools_IndexedDataMapOfShapeShape& FF)
165 //cout<<"FillForOtherEdges"<<endl;
166 // find other pairs for vertexes and edges
167 // creating map of vertex edges for both faces
168 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
169 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
170 if (!FF.Contains(F1))
171 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
172 if (!FF.Contains(E1))
173 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
174 if (!FF.Contains(V1))
175 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
176 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
177 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
178 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
179 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
180 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
182 TopoDS_Edge ES1 = TopoDS::Edge(E1);
183 TopoDS_Edge ES2 = TopoDS::Edge(E2);
184 TopoDS_Shape VS1 = V1;
185 TopoDS_Shape VS2 = V2;
187 ShapeAnalysis_Edge sae;
189 if (!aMapVertEdge1.Contains(VS1))
190 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
191 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
192 //TopoDS_Shape E1next;
193 TopTools_ListIteratorOfListOfShape anIter1(aList1);
194 if (anIter1.Value().IsSame(ES1)) {
197 //E1next = anIter1.Value();
198 if (!aMapVertEdge2.Contains(VS2))
199 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
200 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
201 //TopoDS_Shape E2next;
202 TopTools_ListIteratorOfListOfShape anIter2(aList2);
203 if (anIter2.Value().IsSame(ES2)) {
206 //E2next = anIter2.Value();
207 //ES1 = TopoDS::Edge(E1next);
208 //ES2 = TopoDS::Edge(E2next);
209 ES1 = TopoDS::Edge(anIter1.Value());
210 ES2 = TopoDS::Edge(anIter2.Value());
211 if (!FF.Contains(ES1)) {
214 if (VS1.IsSame(sae.FirstVertex(ES1)))
215 VS1 = sae.LastVertex(ES1);
217 VS1 = sae.FirstVertex(ES1);
218 if (VS2.IsSame(sae.FirstVertex(ES2)))
219 VS2 = sae.LastVertex(ES2);
221 VS2 = sae.FirstVertex(ES2);
224 if (!FF.Contains(VS1)) {
232 //=======================================================================
233 //function : FillCorrespondingEdges
234 //purpose : auxilary for CreatePipeForShellSections()
235 //=======================================================================
236 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
237 const TopoDS_Shape& FS2,
238 const TopoDS_Vertex& aLoc1,
239 const TopoDS_Vertex& aLoc2,
240 const TopoDS_Wire& aWirePath,
241 TopTools_IndexedDataMapOfShapeShape& FF)
243 //cout<<"FillCorrespondingEdges"<<endl;
244 // find corresponding edges
245 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
246 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
247 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
248 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
249 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
250 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
251 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
252 if (theBestMode == GeomFill_IsDiscreteTrihedron)
253 aBuilder.SetDiscreteMode();
254 aBuilder.Add(aWire1, aLoc1);
255 aBuilder.Add(aWire2, aLoc2);
256 if (!aBuilder.IsReady()) {
260 TopoDS_Shape aShape = aBuilder.Shape();
268 BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
270 ShapeAnalysis_Edge sae;
271 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
272 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
273 TopTools_MapOfShape Vs1,Vs2;
275 exp.Init(FS1, TopAbs_EDGE);
276 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
277 TopoDS_Vertex V11 = sae.FirstVertex(E1);
278 TopoDS_Vertex V21 = sae.LastVertex(E1);
279 gp_Pnt P11 = BRep_Tool::Pnt(V11);
280 gp_Pnt P21 = BRep_Tool::Pnt(V21);
281 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
282 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
283 // find corresponding vertexes from created shape
284 TopoDS_Vertex VN11,VN21;
285 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
286 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
287 gp_Pnt P = BRep_Tool::Pnt(V);
288 if (P.Distance(P11)<tol) {
291 if (P.Distance(P21)<tol) {
295 // find edge contains VN11 and VN21 and corresponding vertexes
296 TopoDS_Vertex VN12,VN22;
297 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
298 TopoDS_Shape F = exp.Current();
299 TopExp_Explorer expe;
301 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
302 TopoDS_Edge E = TopoDS::Edge(expe.Current());
303 TopoDS_Vertex VF = sae.FirstVertex(E);
304 TopoDS_Vertex VL = sae.LastVertex(E);
305 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
311 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
312 TopoDS_Edge E = TopoDS::Edge(expe.Current());
313 TopoDS_Vertex VF = sae.FirstVertex(E);
314 TopoDS_Vertex VL = sae.LastVertex(E);
315 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
317 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
319 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
321 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
327 // find vertexes from FS2 corresponded to VN12 and VN22
328 // and find edge from FS2 contains V12 and V22,
329 // this edge will be corresponded to edge E1
330 TopoDS_Vertex V12,V22;
331 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
332 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
333 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
334 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
336 TopExp_Explorer expe;
337 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
338 TopoDS_Edge E = TopoDS::Edge(expe.Current());
339 TopoDS_Vertex VF = sae.FirstVertex(E);
340 TopoDS_Vertex VL = sae.LastVertex(E);
341 gp_Pnt PF = BRep_Tool::Pnt(VF);
342 gp_Pnt PL = BRep_Tool::Pnt(VL);
343 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
349 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
360 // find other pairs for vertexes and edges
361 // creating map of vertex edges for both faces
362 return FillForOtherEdges(FS1,E1,V21,FF);
367 //=======================================================================
368 //function : FillCorrespondingEdges
369 //purpose : auxilary for CreatePipeShellsWithoutPath()
370 //=======================================================================
371 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
372 const TopoDS_Shape& FS2,
373 const TopoDS_Vertex& aLoc1,
374 const TopoDS_Vertex& aLoc2,
375 TopTools_IndexedDataMapOfShapeShape& FF)
377 //cout<<"FillCorrespondingEdges"<<endl;
379 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
380 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
383 ShapeAnalysis_Edge sae;
384 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
385 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
386 TopTools_MapOfShape Vs1,Vs2;
388 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
391 TopExp_Explorer exp1;
392 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
393 E1 = TopoDS::Edge(exp1.Current());
394 TopoDS_Vertex V1 = sae.FirstVertex(E1);
395 TopoDS_Vertex V2 = sae.LastVertex(E1);
396 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
397 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
398 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
399 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
400 if (P1.Distance(Ptmp1)<tol) {
404 if (P1.Distance(Ptmp2)<tol) {
411 TopoDS_Vertex VE21,VE22;
413 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
414 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
415 TopoDS_Vertex V1 = sae.FirstVertex(E);
416 TopoDS_Vertex V2 = sae.LastVertex(E);
417 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
418 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
419 if (P2.Distance(Ptmp1)<tol) {
431 if (P2.Distance(Ptmp2)<tol) {
445 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
446 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
447 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
448 gp_Vec aDir1(PV21,PE21);
449 gp_Vec aDir2(PV21,PE22);
450 double ang1 = aDir.Angle(aDir1);
451 double ang2 = aDir.Angle(aDir2);
452 if (fabs(ang1)<fabs(ang2)) {
465 // find other pairs for vertexes and edges
466 return FillForOtherEdges(FS1,E1,V21,FF);
469 //=======================================================================
470 //function : FindNextPairOfFaces
471 //purpose : auxilary for CreatePipeForShellSections()
472 //=======================================================================
473 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
474 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
475 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
476 TopTools_IndexedDataMapOfShapeShape& FF,
479 //cout<<"FindNextPairOfFaces"<<endl;
480 TopExp_Explorer anExp;
481 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
482 TopoDS_Shape E1 = anExp.Current();
483 if (!FF.Contains(E1)) {
485 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
487 if (!FF.Contains(E1))
488 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
489 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
490 TopExp_Explorer anExpV;
491 anExpV.Init(E1, TopAbs_VERTEX);
492 TopoDS_Shape V1 = anExpV.Current();
493 if (!FF.Contains(V1)) {
495 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
498 if (!aMapEdgeFaces1.Contains(E1))
499 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
500 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
501 if (aList1.Extent()<2)
503 TopTools_ListIteratorOfListOfShape anIter(aList1);
504 if (anIter.Value().IsEqual(aCurFace)) {
507 TopoDS_Shape F1other = anIter.Value();
508 if (FF.Contains(F1other))
511 if (!FF.Contains(aCurFace))
512 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
513 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
514 if (!aMapEdgeFaces2.Contains(E2))
515 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
516 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
517 if (aList2.Extent()<2) {
519 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
521 TopTools_ListIteratorOfListOfShape anIter2(aList2);
522 if (anIter2.Value().IsEqual(F2)) {
525 TopoDS_Shape F2other = anIter2.Value();
526 FF.Add(F1other,F2other);
528 // add pairs of edges to FF
529 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
532 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
535 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
539 //=======================================================================
540 //function : FindFirstPairFaces
541 //purpose : auxilary for Execute()
542 //=======================================================================
543 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
544 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
545 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
547 //cout<<"FindFirstPairFaces"<<endl;
549 // check if vertexes are sub-shapes of sections
550 gp_Pnt P1 = BRep_Tool::Pnt(V1);
551 gp_Pnt P2 = BRep_Tool::Pnt(V2);
552 TopoDS_Vertex V1new,V2new;
554 double mindist = 1.e10;
555 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
556 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
557 gp_Pnt P = BRep_Tool::Pnt(V);
558 double dist = P1.Distance(P);
565 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
566 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
567 gp_Pnt P = BRep_Tool::Pnt(V);
568 double dist = P2.Distance(P);
575 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
576 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
577 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
578 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
579 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
580 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
582 // replace vertexes if it is needed
583 if (!V1.IsSame(V1new)) {
585 P1 = BRep_Tool::Pnt(V1);
586 MESSAGE (" replace V1");
589 MESSAGE (" not replace V1");
590 if (!V2.IsSame(V2new)) {
592 P2 = BRep_Tool::Pnt(V2);
593 MESSAGE (" replace V2");
596 MESSAGE (" not replace V2");
598 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
599 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
600 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
601 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
603 if (!aMapVertFaces1.Contains(V1))
604 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
605 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
606 TopTools_ListIteratorOfListOfShape anIter1(aList1);
607 FS1 = anIter1.Value();
609 double x1=0., y1=0., z1=0.;
611 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
612 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
613 gp_Pnt P = BRep_Tool::Pnt(V);
619 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
621 TColgp_SequenceOfPnt Ps;
622 TopTools_SequenceOfShape Fs;
623 if (!aMapVertFaces2.Contains(V2))
624 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
625 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
626 TopTools_ListIteratorOfListOfShape anIter2(aList2);
627 for (; anIter2.More(); anIter2.Next()) {
628 TopoDS_Shape F = anIter2.Value();
629 double x2=0., y2=0., z2=0.;
631 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
632 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
633 gp_Pnt P = BRep_Tool::Pnt(V);
639 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
646 double MinAng = M_PI;
648 for (; i<=Fs.Length(); i++) {
649 gp_Vec tmpDir(PM1,Ps(i));
650 double ang = fabs(aDir.Angle(tmpDir));
659 //=======================================================================
660 //function : CreatePipeWithDifferentSections
662 //=======================================================================
663 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
664 (const TopoDS_Wire& theWirePath,
665 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
666 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
667 const Standard_Boolean theWithContact,
668 const Standard_Boolean theWithCorrect)
672 TopoDS_Wire aWirePath = theWirePath;
674 Standard_Integer nbBases = theHSeqBases->Length();
675 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
677 if (nbLocs && nbLocs != nbBases) {
678 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
681 TopTools_SequenceOfShape aSeqBases;
682 TopTools_SequenceOfShape aSeqLocs;
683 TopTools_SequenceOfShape aSeqFaces;
685 Standard_Integer i = 1;
686 for (i = 1; i <= nbBases; i++) {
687 if (theHSeqBases->Value(i).IsNull())
690 // Make copy to prevent modifying of base object 0020766 : EDF 1320
691 TopoDS_Shape aShapeBase;
692 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
694 aShapeBase = Copy.Shape();
696 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
698 //if for section was specified face with a few wires then a few
699 // pipes were build and make solid
700 Standard_Boolean NeedCreateSolid = Standard_False;
701 if (aTypeBase == TopAbs_SHELL) {
702 // create wire as boundary contour if shell is no closed
703 // get free boundary shapes
704 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
705 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
706 TopExp_Explorer anExp;
708 Standard_Integer NbWires = 0;
709 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
711 aWire = anExp.Current();
715 Standard_ConstructionError::Raise("Bad shell is used as section ");
717 NeedCreateSolid = Standard_True;
718 aSeqFaces.Append(aShapeBase);
719 aSeqBases.Append(aWire);
721 else if (aTypeBase == TopAbs_FACE) {
722 NeedCreateSolid = Standard_True;
723 //for case one path should be used other type function
724 aSeqFaces.Append(aShapeBase);
725 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
726 for (; aExpW.More(); aExpW.Next()) {
727 TopoDS_Shape aWireProf = aExpW.Current();
728 aSeqBases.Append(aWireProf);
731 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
732 aSeqBases.Append(aShapeBase);
734 else if (aTypeBase == TopAbs_EDGE) {
735 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
736 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
737 aSeqBases.Append(aWireProf);
740 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
741 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
743 aSeqLocs.Append(aShapeLoc);
747 nbLocs = aSeqLocs.Length();
750 TopTools_SequenceOfShape Edges;
752 // we have to check that each location shape is a vertex from
753 // path and update aSeqLocs if it is needed (and possible)
754 TColgp_SequenceOfPnt PLocs;
755 for (i=1; i<=nbLocs; i++) {
756 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
757 PLocs.Append(BRep_Tool::Pnt(V));
759 //TopTools_SequenceOfShape Edges;
760 TopExp_Explorer anExp;
761 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
762 Edges.Append(anExp.Current());
764 int nbEdges = Edges.Length();
765 ShapeAnalysis_Edge sae;
766 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
767 double tol = BRep_Tool::Tolerance(edge);
768 TopoDS_Vertex VF = sae.FirstVertex(edge);
769 gp_Pnt PF = BRep_Tool::Pnt(VF);
770 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
771 if (PF.Distance(PLocs.First()) > tol) {
772 Standard_ConstructionError::Raise
773 ("First location shapes is not coincided with first vertex of aWirePath");
775 aSeqLocs.ChangeValue(1) = VF;
776 edge = TopoDS::Edge(Edges.Last());
777 tol = BRep_Tool::Tolerance(edge);
778 TopoDS_Vertex VL = sae.LastVertex(edge);
779 gp_Pnt PL = BRep_Tool::Pnt(VL);
780 if (PL.Distance(PLocs.Last()) > tol) {
781 Standard_ConstructionError::Raise
782 ("Last location shapes is not coincided with last vertex of aWirePath");
784 aSeqLocs.ChangeValue(nbLocs) = VL;
786 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
787 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
788 tol = BRep_Tool::Tolerance(edge);
789 TopoDS_Vertex V1 = sae.FirstVertex(E);
790 TopoDS_Vertex V2 = sae.LastVertex(E);
791 gp_Pnt P1 = BRep_Tool::Pnt(V1);
792 gp_Pnt P2 = BRep_Tool::Pnt(V2);
793 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
794 aSeqLocs.ChangeValue(jcurr) = V2;
798 // find distance between E and aLocs(jcurr)
800 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
801 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
802 if (PPCurve.NbPoints()>0 &&
803 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
804 double param = PPCurve.Parameter(1);
807 // split current edge
808 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
809 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
814 if (Pfp.Distance(P1)<tol) {
815 B.MakeEdge(E1,tc1,tol);
817 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
818 B.Add(E1,TopoDS::Vertex(tmpV));
819 B.MakeEdge(E2,tc2,tol);
820 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
821 B.Add(E2,TopoDS::Vertex(tmpV));
825 B.MakeEdge(E1,tc2,tol);
826 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
827 B.Add(E1,TopoDS::Vertex(tmpV));
830 B.MakeEdge(E2,tc1,tol);
832 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
833 B.Add(E2,TopoDS::Vertex(tmpV));
838 Edges.InsertAfter(i-1,E1);
839 Edges.InsertAfter(i,E2);
843 if (nbEdges<Edges.Length()) {
844 // one of edges was splitted => we have to update WirePath
848 for (i=1; i<=Edges.Length(); i++) {
849 B.Add(W,TopoDS::Edge(Edges.Value(i)));
855 // check curvature of wire for condition that
856 // max summary angle between directions along
857 // wire path must be < 4*PI. If not - split wire
858 // and seguences of shapes, perform pipe for each
859 // and make sewing after that
864 if ( Edges.Length() > 0 ) {
865 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
868 SumAng = fabs(Vec1.Angle(Vec2));
872 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
874 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
875 for (i=2; i<=Edges.Length(); i++) {
876 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
877 double tol = BRep_Tool::Tolerance(edge);
878 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
880 double ang = fabs(Vec1.Angle(Vec2));
884 SplitEdgeNums.Append(i-1);
886 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
887 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
888 gp_Pnt P = BRep_Tool::Pnt(aVert);
889 if (P1.Distance(P) < tol) {
890 SplitLocNums.Append(j);
900 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
901 TopTools_SequenceOfShape aSeqRes;
902 int nn, num1 = 1, num2 = 1;
903 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
904 // create wirepath and sequences of shapes
908 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
909 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
911 num1 = SplitEdgeNums.Value(nn) + 1;
912 TopTools_SequenceOfShape aTmpSeqBases;
913 TopTools_SequenceOfShape aTmpSeqLocs;
914 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
915 aTmpSeqBases.Append(aSeqBases.Value(i));
916 aTmpSeqLocs.Append(aSeqLocs.Value(i));
918 num2 = SplitLocNums.Value(nn);
920 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
921 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
922 if (theBestMode == GeomFill_IsDiscreteTrihedron)
923 aBuilder.SetDiscreteMode();
924 Standard_Integer nbShapes = aTmpSeqBases.Length();
925 for (i=1; i<=nbShapes; i++) {
926 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
927 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
928 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
930 if (!aBuilder.IsReady()) {
931 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
934 TopoDS_Shape resShape = aBuilder.Shape();
935 aSeqRes.Append(resShape);
937 // create wirepath and sequences of shapes for last part
941 for (i=num1; i<=Edges.Length(); i++) {
942 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
944 TopTools_SequenceOfShape aTmpSeqBases;
945 TopTools_SequenceOfShape aTmpSeqLocs;
946 for (i=num2; i<=aSeqLocs.Length(); i++) {
947 aTmpSeqBases.Append(aSeqBases.Value(i));
948 aTmpSeqLocs.Append(aSeqLocs.Value(i));
950 // make pipe for last part
951 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
952 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
953 if (theBestMode == GeomFill_IsDiscreteTrihedron)
954 aBuilder.SetDiscreteMode();
955 Standard_Integer nbShapes = aTmpSeqBases.Length();
956 for (i=1; i<=nbShapes; i++) {
957 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
958 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
959 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
961 if (!aBuilder.IsReady()) {
962 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
965 TopoDS_Shape resShape = aBuilder.Shape();
966 aSeqRes.Append(resShape);
967 // make sewing for result
968 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
969 aSewing->SetTolerance(Precision::Confusion());
970 aSewing->SetFaceMode(Standard_True);
971 aSewing->SetFloatingEdgesMode(Standard_False);
972 aSewing->SetNonManifoldMode(Standard_False);
973 for (i=1; i<=aSeqRes.Length(); i++) {
974 aSewing->Add(aSeqRes.Value(i));
977 aShape = aSewing->SewedShape();
980 // old implementation without splitting
981 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
982 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
983 if (theBestMode == GeomFill_IsDiscreteTrihedron)
984 aBuilder.SetDiscreteMode();
986 Standard_Integer nbShapes = aSeqBases.Length();
987 Standard_Integer step = nbShapes/nbBases;
989 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
990 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
992 Standard_Integer ind =0;
993 Standard_Real aTolConf = Precision::Confusion();
994 Standard_Real aTolAng = Precision::Angular();
996 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
997 TopTools_SequenceOfShape usedBases;
998 Standard_Integer j = 1;
999 for (; j <= nbBases; j++) {
1000 ind = i + (j-1)*step;
1001 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1002 usedBases.Append(aWireProf);
1004 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1005 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1006 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1009 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1011 if (!aBuilder.IsReady()) {
1012 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1015 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1018 aShape = aBuilder.Shape();
1019 aSeqFaces.Append(aShape);
1020 for (j = 1; j <=usedBases.Length(); j++)
1021 aBuilder.Delete(usedBases.Value(j));
1024 //for case if section is face
1025 if (aSeqFaces.Length() >1) {
1027 TopoDS_Compound aComp;
1028 aB.MakeCompound(aComp);
1029 for (i = 1; i <= aSeqFaces.Length(); i++)
1030 aB.Add(aComp,aSeqFaces.Value(i));
1038 //=======================================================================
1039 //function : CreatePipeForShellSections
1040 //purpose : auxilary for Execute()
1041 //=======================================================================
1042 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1043 GEOMImpl_IPipe* aCI)
1045 //cout<<"CreatePipeForShellSections"<<endl;
1050 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1051 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1052 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1053 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1054 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1055 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1057 Standard_Integer nbBases = aBasesObjs->Length(),
1058 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1059 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1061 if (nbLocs != nbBases) {
1062 if (aCI) delete aCI;
1063 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1065 if (nbSubBases && nbSubBases != nbBases) {
1066 if (aCI) delete aCI;
1067 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1070 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1072 TopTools_SequenceOfShape VLocs;
1073 for (i=1; i<=nbBases; i++) {
1074 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1075 if (anItemLoc.IsNull())
1077 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1078 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1079 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1081 VLocs.Append(aShapeLoc);
1083 nbLocs = VLocs.Length();
1084 if (nbLocs != nbBases) {
1085 if (aCI) delete aCI;
1086 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1088 // split wire path by location points
1089 TColgp_SequenceOfPnt PLocs;
1090 for (i=1; i<=nbLocs; i++) {
1091 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1092 PLocs.Append(BRep_Tool::Pnt(V));
1095 TopTools_SequenceOfShape Edges;
1096 TopTools_SequenceOfShape Wires;
1097 ShapeAnalysis_Edge sae;
1100 TopExp_Explorer anExp;
1101 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1102 Edges.Append(anExp.Current());
1104 Standard_Integer Num1 = 0;
1105 Standard_Integer Num2 = 0;
1106 for (i=1; i<=Edges.Length(); i++) {
1107 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1108 double tol = BRep_Tool::Tolerance(E);
1109 TopoDS_Vertex V1 = sae.FirstVertex(E);
1110 TopoDS_Vertex V2 = sae.LastVertex(E);
1111 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1112 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1113 if (P1.Distance(PLocs.First()) < tol) {
1116 if (P2.Distance(PLocs.Last()) < tol) {
1120 if (Num1>0 && Num2>0) {
1123 for (i=Num1; i<=Num2; i++) {
1124 B.Add(W,Edges.Value(i));
1129 Wires.Append(aWirePath);
1133 TopExp_Explorer anExp;
1134 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1135 Edges.Append(anExp.Current());
1137 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1138 double tol = BRep_Tool::Tolerance(edge);
1139 TopoDS_Vertex VF = sae.FirstVertex(edge);
1140 gp_Pnt PF = BRep_Tool::Pnt(VF);
1141 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1142 if (PF.Distance(PLocs.First()) > tol) {
1143 if (aCI) delete aCI;
1144 Standard_ConstructionError::Raise
1145 ("First location shapes is not coincided with first vertex of aWirePath");
1147 VLocs.ChangeValue(1) = VF;
1148 edge = TopoDS::Edge(Edges.Last());
1149 tol = BRep_Tool::Tolerance(edge);
1150 TopoDS_Vertex VL = sae.LastVertex(edge);
1151 gp_Pnt PL = BRep_Tool::Pnt(VL);
1152 if (PL.Distance(PLocs.Last()) > tol) {
1153 if (aCI) delete aCI;
1154 Standard_ConstructionError::Raise
1155 ("Last location shapes is not coincided with last vertex of aWirePath");
1157 VLocs.ChangeValue(nbLocs) = VL;
1159 TopTools_SequenceOfShape tmpEdges;
1160 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1161 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1162 tol = BRep_Tool::Tolerance(E);
1163 TopoDS_Vertex V1 = sae.FirstVertex(E);
1164 TopoDS_Vertex V2 = sae.LastVertex(E);
1165 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1166 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1167 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1168 // make wire from current edge and add created
1172 for (j=1; j<=tmpEdges.Length(); j++)
1173 B.Add(W,tmpEdges.Value(j));
1176 VLocs.ChangeValue(jcurr) = V2;
1181 // find distance between E and aLocs(jcurr)
1183 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1184 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1185 if (PPCurve.NbPoints()>0 &&
1186 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1187 double param = PPCurve.Parameter(1);
1190 // split current edge
1191 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1192 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1196 if (Pfp.Distance(P1)<tol) {
1197 B.MakeEdge(E1,tc1,tol);
1199 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1200 B.Add(E1,TopoDS::Vertex(tmpV));
1201 tmpEdges.Append(E1);
1202 B.MakeEdge(E2,tc2,tol);
1203 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1204 B.Add(E2,TopoDS::Vertex(tmpV));
1208 B.MakeEdge(E1,tc2,tol);
1209 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1210 B.Add(E1,TopoDS::Vertex(tmpV));
1213 tmpEdges.Append(E1);
1214 B.MakeEdge(E2,tc1,tol);
1216 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1217 B.Add(E2,TopoDS::Vertex(tmpV));
1220 // create wire from tmpEdges
1223 for (j=1; j<=tmpEdges.Length(); j++)
1224 B.Add(W,tmpEdges.Value(j));
1229 Edges.InsertAfter(i-1,E1);
1230 Edges.InsertAfter(i,E2);
1237 // create wire from other edges
1240 for (; i<=Edges.Length(); i++)
1241 B.Add(W,Edges.Value(i));
1243 //cout<<"Wires.Length()="<<Wires.Length()<<endl;
1246 if (Wires.Length() != nbLocs-1) {
1247 if (aCI) delete aCI;
1248 Standard_ConstructionError::Raise
1249 ("One of location shapes is not lied on the path");
1252 //TopTools_SequenceOfShape aSeqBases;
1253 //TopTools_SequenceOfShape aSeqSubBases;
1254 //TopTools_SequenceOfShape aSeqFaces;
1255 TopoDS_Compound aComp;
1256 B.MakeCompound(aComp);
1257 for (i = 1; i < nbBases; i++) {
1258 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1260 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1261 if (anItem1.IsNull())
1263 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1264 if (aRefBase1.IsNull())
1266 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1267 if (aShBase1.IsNull())
1269 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1271 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1272 if (anItem2.IsNull())
1274 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1275 if (aRefBase2.IsNull())
1277 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1278 if (aShBase2.IsNull())
1280 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1282 //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
1284 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1285 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1287 if (aCI) delete aCI;
1288 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1291 bool CreateFewSolids = false;
1293 TopExp_Explorer anExp;
1294 Standard_Integer nbf1 = 0;
1295 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1298 Standard_Integer nbf2 = 0;
1299 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1303 CreateFewSolids = true;
1307 // check orientation of sections
1308 bool NeedReverse = false;
1311 anExp.Init(aShBase1, TopAbs_FACE);
1312 TopoDS_Shape aFace = anExp.Current();
1313 TColgp_SequenceOfPnt aPnts;
1314 double xc=0, yc=0, zc=0;
1315 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1316 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1317 aPnts.Append(BRep_Tool::Pnt(V));
1318 xc += aPnts.Last().X();
1319 yc += aPnts.Last().Y();
1320 zc += aPnts.Last().Z();
1322 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1323 gp_Vec V1(PC,aPnts.Value(1));
1324 gp_Vec V2(PC,aPnts.Value(2));
1325 gp_Vec VN = V1.Crossed(V2);
1326 for (int ip=2; ip<aPnts.Length(); ip++) {
1327 V1 = gp_Vec(PC,aPnts.Value(ip));
1328 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1329 VN.Add(V1.Crossed(V2));
1332 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
1334 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1335 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1336 double tol = BRep_Tool::Tolerance(edge);
1337 TopoDS_Vertex VF = sae.FirstVertex(edge);
1338 gp_Pnt PF = BRep_Tool::Pnt(VF);
1339 if (PF.Distance(PLoc) < tol) {
1341 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1344 if (P1.Distance(PLoc) < tol) {
1345 C->D0(fp+(lp-fp)/100,P2);
1349 C->D0(lp+(fp-lp)/100,P2);
1351 PathNorm = gp_Vec(P1,P2);
1355 TopoDS_Vertex VL = sae.LastVertex(edge);
1356 gp_Pnt PL = BRep_Tool::Pnt(VL);
1357 if (PL.Distance(PLoc) < tol) {
1359 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1362 if (P1.Distance(PLoc) < tol) {
1363 C->D0(fp+(lp-fp)/100,P2);
1367 C->D0(lp+(fp-lp)/100,P2);
1369 PathNorm = gp_Vec(P2,P1);
1374 cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1375 cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1376 if (fabs(VN.Angle(PathNorm))>PI/2.) {
1383 anExp.Init(aShBase2, TopAbs_FACE);
1384 TopoDS_Shape aFace = anExp.Current();
1385 TColgp_SequenceOfPnt aPnts;
1386 double xc=0, yc=0, zc=0;
1387 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1388 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1389 aPnts.Append(BRep_Tool::Pnt(V));
1390 xc += aPnts.Last().X();
1391 yc += aPnts.Last().Y();
1392 zc += aPnts.Last().Z();
1394 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1395 gp_Vec V1(PC,aPnts.Value(1));
1396 gp_Vec V2(PC,aPnts.Value(2));
1397 gp_Vec VN = V1.Crossed(V2);
1398 for (int ip=2; ip<aPnts.Length(); ip++) {
1399 V1 = gp_Vec(PC,aPnts.Value(ip));
1400 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1401 VN.Add(V1.Crossed(V2));
1404 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
1406 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1407 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1408 double tol = BRep_Tool::Tolerance(edge);
1409 TopoDS_Vertex VF = sae.FirstVertex(edge);
1410 gp_Pnt PF = BRep_Tool::Pnt(VF);
1411 if (PF.Distance(PLoc) < tol) {
1413 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1416 if (P1.Distance(PLoc) < tol) {
1417 C->D0(fp+(lp-fp)/100,P2);
1421 C->D0(lp+(fp-lp)/100,P2);
1423 PathNorm = gp_Vec(P2,P1);
1427 TopoDS_Vertex VL = sae.LastVertex(edge);
1428 gp_Pnt PL = BRep_Tool::Pnt(VL);
1429 if (PL.Distance(PLoc) < tol) {
1431 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1434 if (P1.Distance(PLoc) < tol) {
1435 C->D0(fp+(lp-fp)/100,P2);
1439 C->D0(lp+(fp-lp)/100,P2);
1441 PathNorm = gp_Vec(P2,P1);
1446 //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1447 //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1448 if (fabs(VN.Angle(PathNorm))>PI/2.)
1453 if (!CreateFewSolids) {
1454 // we can create only one solid
1455 TopoDS_Shape aWire1, aWire2;
1457 if (aType1==TopAbs_SHELL) {
1458 // create wire as boundary contour if shell is no closed
1459 // get free boundary shapes
1460 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1461 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1462 //TopExp_Explorer anExp;
1463 Standard_Integer NbWires = 0;
1464 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1466 aWire1 = anExp.Current();
1470 if (aCI) delete aCI;
1471 Standard_ConstructionError::Raise("Bad shell is used as section ");
1474 else { // aType1==TopAbs_FACE
1475 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1476 aWire1 = aExpW.Current();
1479 if (aType2==TopAbs_SHELL) {
1480 // create wire as boundary contour if shell is no closed
1481 // get free boundary shapes
1482 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1483 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1484 //TopExp_Explorer anExp;
1485 Standard_Integer NbWires = 0;
1486 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1488 aWire2 = anExp.Current();
1492 if (aCI) delete aCI;
1493 Standard_ConstructionError::Raise("Bad shell is used as section ");
1496 else { // aType2==TopAbs_FACE
1497 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1498 aWire2 = aExpW.Current();
1500 // make pipe using aWire1 and aWire2
1501 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1502 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1503 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1504 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1505 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1506 aBuilder.SetDiscreteMode();
1507 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1508 aWithContact, aWithCorrect);
1509 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1510 aWithContact, aWithCorrect);
1511 if (!aBuilder.IsReady()) {
1512 if (aCI) delete aCI;
1513 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1516 TopoDS_Shape aShape = aBuilder.Shape();
1517 TopoDS_Shell aShell;
1518 B.MakeShell(aShell);
1519 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1520 B.Add(aShell,anExp.Current());
1522 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1523 B.Add(aShell,anExp.Current());
1525 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1526 B.Add(aShell,anExp.Current());
1528 // make sewing for this shell
1529 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1530 aSewing->SetTolerance(Precision::Confusion());
1531 aSewing->SetFaceMode(Standard_True);
1532 aSewing->SetFloatingEdgesMode(Standard_False);
1533 aSewing->SetNonManifoldMode(Standard_False);
1534 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1535 aSewing->Add(anExp.Current());
1538 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1539 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1540 aShell = TopoDS::Shell(aSewShape);
1541 GProp_GProps aSystem;
1542 BRepGProp::VolumeProperties(aShell, aSystem);
1543 if (aSystem.Mass()<0) {
1546 if (BRep_Tool::IsClosed(aShell)) {
1547 TopoDS_Solid aSolid;
1548 B.MakeSolid(aSolid);
1549 B.Add(aSolid,aShell);
1550 B.Add(aComp,aSolid);
1553 B.Add(aComp,aShell);
1557 B.Add(aComp,aShell);
1562 // main block - creation few solids (for each pair of faces)
1563 TopTools_MapOfShape aFaces1,aFaces2;
1564 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1565 aFaces1.Add(anExp.Current());
1567 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1568 aFaces2.Add(anExp.Current());
1570 // creating map of edge faces
1571 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1572 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1573 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1574 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1576 // constuct map face->face
1577 TopTools_IndexedDataMapOfShapeShape FF;
1578 TopoDS_Shape FS1,FS2;
1579 if (nbSubBases==0) {
1580 // find edge the most distant from location point
1581 // (this edge is not shared by two faces)
1582 double maxdist = 0.;
1584 TopoDS_Vertex V11,V21;
1585 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1586 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1587 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1588 if (aList.Extent()>1)
1590 TopExp_Explorer expv;
1591 expv.Init(tmp, TopAbs_VERTEX);
1592 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1594 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1595 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1596 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1597 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1602 TopTools_ListIteratorOfListOfShape anIter(aList);
1603 FS1 = anIter.Value();
1607 // main direction for comparing
1608 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1609 // find corresponding edge from next section
1610 double minang = M_PI;
1611 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1612 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1614 TopoDS_Vertex V12,V22;
1615 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1616 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1617 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1618 if (aList.Extent()>1)
1620 TopExp_Explorer expv;
1621 expv.Init(tmp, TopAbs_VERTEX);
1622 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1624 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1625 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1626 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1627 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1628 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1629 TopoDS_Vertex V1,V2;
1632 V1 = V2tmp; P1 = P2tmp;
1633 V2 = V1tmp; P2 = P1tmp;
1636 V1 = V1tmp; P1 = P1tmp;
1637 V2 = V2tmp; P2 = P2tmp;
1639 gp_Vec Vec1(P11,P1);
1640 gp_Vec Vec2(P21,P2);
1641 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1646 TopTools_ListIteratorOfListOfShape anIter(aList);
1647 FS2 = anIter.Value();
1651 // put all pairs to map FF
1657 // add pairs of edges to FF
1658 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1660 if (aCI) delete aCI;
1661 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1667 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1668 if (anItem.IsNull()) {
1669 if (aCI) delete aCI;
1670 Standard_ConstructionError::Raise("Invalid subbase shape");
1672 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1673 if (aRefBase.IsNull()) {
1674 if (aCI) delete aCI;
1675 Standard_ConstructionError::Raise("Invalid subbase shape");
1677 TopoDS_Shape aSh = aRefBase->GetValue();
1679 if (aCI) delete aCI;
1680 Standard_ConstructionError::Raise("Invalid subbase shape");
1682 if (aSh.ShapeType()!=TopAbs_FACE) {
1683 if (aCI) delete aCI;
1684 Standard_ConstructionError::Raise("Invalid subbase shape");
1689 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1690 if (anItem.IsNull()) {
1691 if (aCI) delete aCI;
1692 Standard_ConstructionError::Raise("Invalid subbase shape");
1694 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1695 if (aRefBase.IsNull()) {
1696 if (aCI) delete aCI;
1697 Standard_ConstructionError::Raise("Invalid subbase shape");
1699 TopoDS_Shape aSh = aRefBase->GetValue();
1701 if (aCI) delete aCI;
1702 Standard_ConstructionError::Raise("Invalid subbase shape");
1704 if (aSh.ShapeType()!=TopAbs_FACE) {
1705 if (aCI) delete aCI;
1706 Standard_ConstructionError::Raise("Invalid subbase shape");
1711 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1712 if (aCI) delete aCI;
1713 Standard_ConstructionError::Raise("Invalid subbase shape");
1718 // add pairs of edges to FF
1719 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1720 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1722 if (aCI) delete aCI;
1723 Standard_ConstructionError::Raise("Can not create correct pipe");
1727 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1729 // make pipe for each pair of faces
1730 for (j=1; j<=FF.Extent(); j++) {
1731 TopoDS_Shape F1 = FF.FindKey(j);
1732 if (F1.ShapeType() != TopAbs_FACE)
1734 TopoDS_Shape F2 = FF.FindFromIndex(j);
1735 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1736 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1737 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1738 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1739 // make pipe using aWire1 and aWire2
1740 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1741 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1742 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1743 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1744 aBuilder.SetDiscreteMode();
1745 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1746 aWithContact, aWithCorrect);
1747 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1748 aWithContact, aWithCorrect);
1749 if (!aBuilder.IsReady()) {
1750 if (aCI) delete aCI;
1751 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1754 TopoDS_Shape aShape = aBuilder.Shape();
1755 TopoDS_Shell aShell;
1756 B.MakeShell(aShell);
1757 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1758 B.Add(aShell,anExp.Current());
1763 // make sewing for this shell
1764 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1765 aSewing->SetTolerance(Precision::Confusion());
1766 aSewing->SetFaceMode(Standard_True);
1767 aSewing->SetFloatingEdgesMode(Standard_False);
1768 aSewing->SetNonManifoldMode(Standard_False);
1769 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1770 aSewing->Add(anExp.Current());
1773 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1774 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1775 aShell = TopoDS::Shell(aSewShape);
1776 GProp_GProps aSystem;
1777 BRepGProp::VolumeProperties(aShell, aSystem);
1778 if (aSystem.Mass()<0) {
1779 //cout<<"aSewShape is reversed"<<endl;
1782 if (BRep_Tool::IsClosed(aShell)) {
1783 TopoDS_Solid aSolid;
1784 B.MakeSolid(aSolid);
1785 B.Add(aSolid,aShell);
1786 B.Add(aComp,aSolid);
1789 B.Add(aComp,aShell);
1793 B.Add(aComp,aShell);
1801 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
1805 //=======================================================================
1806 //function : CreatePipeShellsWithoutPath
1807 //purpose : auxilary for Execute()
1808 //=======================================================================
1809 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
1811 //cout<<"CreatePipeShellsWithoutPath"<<endl;
1815 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1817 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1818 // vertex for recognition
1819 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
1821 Standard_Integer nbBases = aBasesObjs->Length(),
1822 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
1824 if (nbv != nbBases) {
1825 if (aCI) delete aCI;
1826 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
1829 TopTools_SequenceOfShape SecVs,Bases;
1830 for (i=1; i<=nbBases; i++) {
1832 Handle(Standard_Transient) anItem = VObjs->Value(i);
1833 if (anItem.IsNull())
1835 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
1836 TopoDS_Shape V = aRef->GetValue();
1837 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
1841 anItem = aBasesObjs->Value(i);
1842 if (anItem.IsNull())
1844 aRef = Handle(GEOM_Function)::DownCast(anItem);
1845 TopoDS_Shape aSh = aRef->GetValue();
1850 nbv = SecVs.Length();
1851 nbBases = Bases.Length();
1852 if (nbv != nbBases) {
1853 if (aCI) delete aCI;
1854 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
1857 TopoDS_Compound aComp;
1858 B.MakeCompound(aComp);
1860 for (i = 1; i < nbBases; i++) {
1861 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
1862 TopoDS_Shape aShBase1 = Bases.Value(i);
1863 TopoDS_Shape aShBase2 = Bases.Value(i+1);
1864 TopExp_Explorer anExp;
1865 Standard_Integer nbf1 = 0;
1866 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1869 Standard_Integer nbf2 = 0;
1870 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1873 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
1875 if (aCI) delete aCI;
1876 Standard_ConstructionError::Raise("Different number of faces in the sections");
1879 TopTools_MapOfShape aFaces1,aFaces2;
1880 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1881 aFaces1.Add(anExp.Current());
1883 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1884 aFaces2.Add(anExp.Current());
1887 // creating map of edge faces
1888 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1889 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1890 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1891 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1893 // constuct map face->face (and sub-shapes)
1894 TopTools_IndexedDataMapOfShapeShape FF;
1895 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
1896 TopoDS_Shape FS1, FS2;
1897 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
1898 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
1899 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
1902 MESSAGE (" first pair of corresponding faces is found");
1904 // add pairs of edges and vertexes to FF
1905 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
1907 if (aCI) delete aCI;
1908 Standard_ConstructionError::Raise("Can not create correct pipe");
1910 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
1912 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1913 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
1915 // make pipe for each pair of faces
1916 // auxilary map vertex->edge for created pipe edges
1917 TopTools_IndexedDataMapOfShapeShape VPE;
1918 ShapeAnalysis_Edge sae;
1919 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
1921 for (j=1; j<=FF.Extent(); j++) {
1922 TopoDS_Shape F1 = FF.FindKey(j);
1923 if (F1.ShapeType() != TopAbs_FACE)
1925 TopoDS_Shape F2 = FF.FindFromIndex(j);
1928 //if (nbff!=3) continue;
1930 MESSAGE (" make pipe for "<<nbff<<" face");
1932 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
1933 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1934 Handle(Geom_RectangularTrimmedSurface) RTS =
1935 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
1936 S1 = RTS->BasisSurface();
1938 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
1939 if (Pln1.IsNull()) {
1940 if (aCI) delete aCI;
1941 Standard_ConstructionError::Raise("Surface from face is not plane");
1943 gp_Vec aDir1(Pln1->Axis().Direction());
1945 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
1946 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1947 Handle(Geom_RectangularTrimmedSurface) RTS =
1948 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
1949 S2 = RTS->BasisSurface();
1951 Handle(Geom_Plane) Pln2 =
1952 Handle(Geom_Plane)::DownCast(S2);
1953 if (Pln2.IsNull()) {
1954 if (aCI) delete aCI;
1955 Standard_ConstructionError::Raise("Surface from face is not plane");
1957 gp_Vec aDir2(Pln2->Axis().Direction());
1959 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
1960 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
1962 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
1964 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
1967 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
1968 TopTools_SequenceOfShape aNewFs;
1970 for (; anExpE.More(); anExpE.Next()) {
1971 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
1973 if (!FF.Contains(E1))
1974 MESSAGE ("map FF not contains key E1");
1976 if (VPE.Contains(E1)) {
1977 aNewFs.Append(VPE.FindFromKey(E1));
1979 MESSAGE (" using existed face");
1984 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
1985 TopoDS_Vertex V1 = sae.FirstVertex(E1);
1986 TopoDS_Vertex V2 = sae.LastVertex(E1);
1987 if (!FF.Contains(V1))
1988 MESSAGE ("map FF not contains key V1");
1989 if (!FF.Contains(V2))
1990 MESSAGE ("map FF not contains key V2");
1991 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
1992 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
1993 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
1994 if (Vtmp.IsSame(V4))
1996 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1997 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1998 gp_Pnt P3 = BRep_Tool::Pnt(V3);
1999 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2002 Handle(Geom_BSplineCurve) C2;
2003 if (VPE.Contains(V2)) {
2004 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2006 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2009 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2010 HAP->SetValue(1,P2);
2011 HAP->SetValue(2,P3);
2012 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2013 anInt.Load(aDir1,aDir2);
2016 B.MakeEdge(E2,C2,1.e-7);
2017 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2018 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2023 Handle(Geom_BSplineCurve) C4;
2024 if (VPE.Contains(V1)) {
2025 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2027 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2030 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2031 HAP->SetValue(1,P1);
2032 HAP->SetValue(2,P4);
2033 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2034 anInt.Load(aDir1,aDir2);
2037 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2038 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2039 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2048 B.Add(W,E4.Reversed());
2049 //cout<<" wire for edge "<<nbee<<" is created"<<endl;
2050 //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
2055 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2056 //bool IsConicC1 = false;
2057 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2058 // IsConicC1 = true;
2059 // cout<<"C1 - Geom_Conic"<<endl;
2061 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2062 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2065 // double tol = BRep_Tool::Tolerance(E1);
2066 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2067 // C1 = ApxC1.Curve();
2069 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2070 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2071 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2076 Handle(Geom_BSplineCurve) CE1 =
2077 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2078 if (CE1->Degree()<3)
2079 CE1->IncreaseDegree(3);
2080 Handle(Geom_BSplineCurve) CE2 =
2081 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2082 if (CE2->Degree()<3)
2083 CE2->IncreaseDegree(3);
2084 Handle(Geom_BSplineCurve) CE3 =
2085 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2086 if (CE3->Degree()<3)
2087 CE3->IncreaseDegree(3);
2088 Handle(Geom_BSplineCurve) CE4 =
2089 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2090 if (CE4->Degree()<3)
2091 CE4->IncreaseDegree(3);
2092 //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
2093 // <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
2094 //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
2095 // os<<"DrawTrSurf_BSplineCurve"<<endl;
2096 // GeomTools::Write(CE1,os);
2100 Handle(Geom_Surface) BS;
2102 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2103 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2107 MESSAGE (" can not create BSplineSurface - create Bezier");
2109 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2110 double fp1,lp1,fp2,lp2;
2111 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2112 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2121 // get points from C1
2122 if (P1.Distance(P1C1)<1.e-6) {
2130 double step = (lp-fp)/(NbP-1);
2131 Points.SetValue(1,1,P1);
2133 for (n1=2; n1<NbP; n1++) {
2137 Points.SetValue(1,n1,P);
2139 Points.SetValue(1,NbP,P2);
2140 // get points from C3
2141 if (P4.Distance(P1C3)<1.e-6) {
2149 step = (lp-fp)/(NbP-1);
2150 Points.SetValue(NbP,1,P4);
2152 for (n1=2; n1<NbP; n1++) {
2156 Points.SetValue(NbP,n1,P);
2158 Points.SetValue(NbP,NbP,P3);
2159 // create isolines and get points from them
2160 for (n1=1; n1<=NbP; n1++) {
2161 gp_Pnt PI1 = Points.Value(1,n1);
2162 gp_Pnt PI2 = Points.Value(NbP,n1);
2163 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2164 HAP->SetValue(1,PI1);
2165 HAP->SetValue(2,PI2);
2166 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2167 anInt.Load(aDir1,aDir2);
2169 Handle(Geom_Curve) iso = anInt.Curve();
2170 fp = iso->FirstParameter();
2171 lp = iso->LastParameter();
2172 step = (lp-fp)/(NbP-1);
2174 TopoDS_Compound VComp;
2175 B.MakeCompound(VComp);
2176 for (n2=2; n2<NbP; n2++) {
2180 Points.SetValue(n2,n1,P);
2183 // create surface and face
2184 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2185 BS = new Geom_BezierSurface(Points);
2188 BRepBuilderAPI_MakeFace BB(BS,W);
2189 TopoDS_Face NewF = BB.Face();
2190 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2192 sff->FixOrientation();
2193 TopoDS_Face FixedFace = sff->Face();
2194 aNewFs.Append(FixedFace);
2195 VPE.Add(E1,FixedFace);
2196 //cout<<" face for edge "<<nbee<<" is created"<<endl;
2197 //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
2200 TopoDS_Shell aShell;
2201 B.MakeShell(aShell);
2202 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2203 B.Add(aShell,aNewFs(nf));
2208 // make sewing for this shell
2209 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2210 aSewing->SetTolerance(Precision::Confusion());
2211 aSewing->SetFaceMode(Standard_True);
2212 aSewing->SetFloatingEdgesMode(Standard_False);
2213 aSewing->SetNonManifoldMode(Standard_False);
2214 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2215 aSewing->Add(anExp.Current());
2218 MESSAGE (" shell for face "<<nbff<<" is created");
2219 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2220 //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
2221 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2222 aShell = TopoDS::Shell(aSewShape);
2223 GProp_GProps aSystem;
2224 BRepGProp::VolumeProperties(aShell, aSystem);
2225 if (aSystem.Mass()<0) {
2226 //cout<<"aSewShape is reversed"<<endl;
2229 if (BRep_Tool::IsClosed(aShell)) {
2230 TopoDS_Solid aSolid;
2231 B.MakeSolid(aSolid);
2232 B.Add(aSolid,aShell);
2233 B.Add(aComp,aSolid);
2234 MESSAGE (" solid for face "<<nbff<<" is created");
2237 B.Add(aComp,aShell);
2238 MESSAGE (" solid for face "<<nbff<<" is not created");
2242 B.Add(aComp,aShell);
2243 MESSAGE (" solid for face "<<nbff<<" is not created");
2245 //cout<<" solid for face "<<nbff<<" is created"<<endl;
2247 //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
2249 //TopoDS_Shell FixedShell = sfs->Shell();
2251 GProp_GProps aSystem;
2252 BRepGProp::VolumeProperties(FixedShell, aSystem);
2253 if (aSystem.Mass()<0) {
2254 //cout<<"aSewShape is reversed"<<endl;
2255 FixedShell.Reverse();
2257 if (BRep_Tool::IsClosed(FixedShell)) {
2258 TopoDS_Solid aSolid;
2259 B.MakeSolid(aSolid);
2260 B.Add(aSolid,aShell);
2261 B.Add(aComp,aSolid);
2264 B.Add(aComp,FixedShell);
2270 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
2274 //=======================================================================
2275 //function : CreatePipeBiNormalAlongVector
2276 //purpose : auxilary for Execute()
2277 //=======================================================================
2278 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2279 GEOMImpl_IPipe* aCI)
2281 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2283 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2284 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2285 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2286 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2288 if (aShapeBase.IsNull()) {
2289 if (aCIBN) delete aCIBN;
2290 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2293 // Make copy to prevent modifying of base object: 0021525
2294 BRepBuilderAPI_Copy Copy (aShapeBase);
2296 aShapeBase = Copy.Shape();
2299 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2302 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2303 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2305 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2308 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2309 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2310 aProf = wexp.Current();
2313 Standard_TypeMismatch::Raise
2314 ("MakePipe aborted : invalid type of base");
2316 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2317 PipeBuilder.Add(aProf);
2319 if (aShapeVec.IsNull()) {
2320 if (aCIBN) delete aCIBN;
2321 Standard_NullObject::Raise
2322 ("MakePipe aborted : null vector argument");
2324 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2325 Standard_TypeMismatch::Raise
2326 ("MakePipe aborted: invalid type of vector");
2327 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2328 TopoDS_Vertex V1, V2;
2329 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2330 if (V1.IsNull() || V2.IsNull())
2331 Standard_NullObject::Raise
2332 ("MakePipe aborted: vector is not defined");
2333 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2334 gp_Dir BiNormal(aVec);
2335 PipeBuilder.SetMode(BiNormal);
2336 PipeBuilder.Build();
2337 if (aShapeBase.ShapeType() == TopAbs_FACE) {
2338 PipeBuilder.MakeSolid();
2341 return PipeBuilder.Shape();
2344 //=======================================================================
2345 //function : Execute
2347 //=======================================================================
2348 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
2350 if (Label().IsNull()) return 0;
2351 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
2352 Standard_Integer aType = aFunction->GetType();
2354 GEOMImpl_IPipe* aCI = 0;
2355 if (aType == PIPE_BASE_PATH)
2356 aCI = new GEOMImpl_IPipe (aFunction);
2357 else if (aType == PIPE_DIFFERENT_SECTIONS)
2358 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
2359 else if (aType == PIPE_SHELL_SECTIONS)
2360 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2361 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
2362 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2363 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
2364 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
2368 TopoDS_Wire aWirePath;
2369 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
2370 // working with path
2371 Handle(GEOM_Function) aRefPath = aCI->GetPath();
2372 TopoDS_Shape aShapePath = aRefPath->GetValue();
2374 if (aShapePath.IsNull()) {
2375 MESSAGE ("Driver : path is null");
2376 if (aCI) delete aCI;
2377 Standard_NullObject::Raise("MakePipe aborted : null path argument");
2382 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
2383 TopTools_SequenceOfShape anEdges;
2384 TopExp_Explorer anExp;
2388 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2389 B.Add(W, anExp.Current());
2395 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
2396 aWirePath = TopoDS::Wire(aShapePath);
2400 if (aShapePath.ShapeType() == TopAbs_EDGE) {
2401 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
2402 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
2407 if (aCI) delete aCI;
2408 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
2412 TopoDS_Shape aShape;
2414 if (aType == PIPE_BASE_PATH) {
2415 Handle(GEOM_Function) aRefBase = aCI->GetBase();
2416 TopoDS_Shape aShapeBase;
2418 // Make copy to prevent modifying of base object 0020766 : EDF 1320
2419 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
2421 aShapeBase = Copy.Shape();
2423 if (aShapeBase.IsNull()) {
2424 if (aCI) delete aCI;
2425 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2429 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
2430 aShapeBase.ShapeType() == TopAbs_WIRE)
2432 TopoDS_Wire Profile;
2433 if (aShapeBase.ShapeType() == TopAbs_WIRE)
2434 Profile = TopoDS::Wire(aShapeBase);
2438 BB.MakeWire(Profile);
2439 BB.Add(Profile, aShapeBase);
2442 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
2443 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
2444 if (FaceBuilder.IsDone())
2445 Sweep.SetMode(FaceBuilder.Face());
2449 if (!Sweep.IsDone())
2451 if (aCI) delete aCI;
2452 Standard_ConstructionError::Raise("MakePipeShell failed");
2455 aShape = Sweep.Shape(); //result is good
2460 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
2461 aShape = BRepOffsetAPI_MakePipe(aWirePath, aShapeBase, theBestMode);
2465 //building pipe with different sections
2466 else if (aType == PIPE_DIFFERENT_SECTIONS) {
2467 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
2468 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
2469 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
2470 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
2471 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
2477 Standard_Integer nbBases = aBasesObjs->Length();
2478 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
2480 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
2481 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
2484 for (i = 1; i <= nbBases; i++) {
2485 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
2486 if (anItem.IsNull())
2488 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
2489 if (aRefBase.IsNull())
2491 if (aRefBase->GetValue().IsNull())
2494 aHSeqBases->Append(aRefBase->GetValue());
2496 for (i = 1; i <= nbLocs; i++) {
2497 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
2498 if (anItemLoc.IsNull())
2500 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
2501 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
2502 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
2505 aHSeqLocs->Append(aShapeLoc);
2508 aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
2511 //building pipe with shell sections
2512 else if (aType == PIPE_SHELL_SECTIONS) {
2513 aShape = CreatePipeForShellSections(aWirePath,aCI);
2516 //building pipe shell sections without path
2517 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
2518 aShape = CreatePipeShellsWithoutPath(aCI);
2521 //building a pipe with constant bi-normal along given vector
2522 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
2523 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
2531 if (aShape.IsNull()) return 0;
2533 BRepCheck_Analyzer ana (aShape, Standard_False);
2534 if (!ana.IsValid()) {
2535 ShapeFix_ShapeTolerance aSFT;
2536 aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
2537 Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
2538 aSfs->SetPrecision(Precision::Confusion());
2540 aShape = aSfs->Shape();
2542 ana.Init(aShape, Standard_False);
2544 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
2547 if (aType != PIPE_BASE_PATH &&
2548 aType != PIPE_SHELLS_WITHOUT_PATH) {
2549 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
2550 if (anExpV.More()) {
2551 Standard_Real aVertMaxTol = -RealLast();
2552 for (; anExpV.More(); anExpV.Next()) {
2553 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
2554 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
2555 if (aTol > aVertMaxTol)
2558 aVertMaxTol += Precision::Confusion();
2559 aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
2560 //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
2564 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
2565 aFunction->SetValue(aRes);
2567 log.SetTouched(Label());
2571 //================================================================================
2573 * \brief Returns a name of creation operation and names and values of creation parameters
2575 //================================================================================
2577 bool GEOMImpl_PipeDriver::
2578 GetCreationInformation(std::string& theOperationName,
2579 std::vector<GEOM_Param>& theParams)
2581 if (Label().IsNull()) return 0;
2582 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
2583 Standard_Integer aType = function->GetType();
2586 case PIPE_BASE_PATH:
2588 theOperationName = "PIPE";
2589 GEOMImpl_IPipe aCI( function );
2590 AddParam( theParams, "Base Object", aCI.GetBase() );
2591 AddParam( theParams, "Path Object", aCI.GetPath() );
2594 case PIPE_BI_NORMAL_ALONG_VECTOR:
2596 theOperationName = "PIPE";
2597 GEOMImpl_IPipeBiNormal aCI( function );
2598 AddParam( theParams, "Base Object", aCI.GetBase() );
2599 AddParam( theParams, "Path Object", aCI.GetPath() );
2600 AddParam( theParams, "BiNormal", aCI.GetVector() );
2603 case PIPE_DIFFERENT_SECTIONS:
2605 theOperationName = "PIPE";
2606 GEOMImpl_IPipeDiffSect aCI( function );
2607 AddParam( theParams, "Bases", aCI.GetBases() );
2608 AddParam( theParams, "Locations", aCI.GetLocations() );
2609 AddParam( theParams, "Path", aCI.GetPath() );
2610 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
2611 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
2614 case PIPE_SHELL_SECTIONS:
2616 theOperationName = "PIPE";
2617 GEOMImpl_IPipeShellSect aCI( function );
2618 AddParam( theParams, "Bases", aCI.GetBases() );
2619 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
2620 AddParam( theParams, "Locations", aCI.GetLocations() );
2621 AddParam( theParams, "Path", aCI.GetPath() );
2622 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
2623 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
2626 case PIPE_SHELLS_WITHOUT_PATH:
2628 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
2629 GEOMImpl_IPipeShellSect aCI( function );
2630 AddParam( theParams, "Bases", aCI.GetBases() );
2631 AddParam( theParams, "Locations", aCI.GetLocations() );
2641 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
2642 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);