1 // Created on: 1996-09-04
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BSplCLib.hxx>
21 #include <Geom_BSplineCurve.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_Plane.hxx>
24 #include <Geom_RectangularTrimmedSurface.hxx>
25 #include <Geom_Surface.hxx>
26 #include <GeomConvert.hxx>
29 #include <LocOpe_BuildShape.hxx>
30 #include <LocOpe_Pipe.hxx>
31 #include <Precision.hxx>
32 #include <Standard_DomainError.hxx>
33 #include <Standard_NoSuchObject.hxx>
34 #include <TColgp_Array1OfPnt.hxx>
35 #include <TColStd_Array1OfInteger.hxx>
36 #include <TColStd_Array1OfReal.hxx>
38 #include <TopExp_Explorer.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopoDS_Wire.hxx>
44 #include <TopTools_DataMapOfShapeListOfShape.hxx>
45 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopTools_MapIteratorOfMapOfShape.hxx>
48 #include <TopTools_MapOfShape.hxx>
50 static TopAbs_Orientation Orientation(const TopoDS_Shape&,
54 //=======================================================================
55 //function : LocOpe_Pipe
57 //=======================================================================
59 LocOpe_Pipe::LocOpe_Pipe(const TopoDS_Wire& Spine,
60 const TopoDS_Shape& Profile) :
64 TopoDS_Shape Result = myPipe.Shape();
66 // On enleve les faces generees par les edges de connexite du profile,
67 // et on fusionne les plans si possible
69 TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
70 TopExp::MapShapesAndAncestors(Profile,TopAbs_EDGE,TopAbs_FACE,theEFMap);
72 TopTools_ListOfShape Empty;
73 TopTools_ListIteratorOfListOfShape it;
75 TopTools_ListOfShape goodfaces;
77 for (Standard_Integer i=1; i<=theEFMap.Extent(); i++) {
78 const TopoDS_Edge& edgpr = TopoDS::Edge(theEFMap.FindKey(i));
79 myMap.Bind(edgpr,Empty);
80 if (theEFMap(i).Extent() >= 2) {
81 // on ne prend pas les faces generees
84 TopTools_MapOfShape MapFac; // on mappe les plans generes par cet edge
85 for (exp.Init(Spine,TopAbs_EDGE); exp.More(); exp.Next()) {
86 const TopoDS_Edge& edgsp = TopoDS::Edge(exp.Current());
87 TopoDS_Face resfac = myPipe.Face(edgsp,edgpr);
88 if (!resfac.IsNull()) {
89 Handle(Geom_Surface) P = BRep_Tool::Surface(resfac);
90 if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
91 P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
93 if (P->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
97 myMap(edgpr).Append(resfac);
98 goodfaces.Append(resfac);
103 // Chercher les composantes connexes sur cet ensemble de faces., avec meme
104 // support geometrique
106 TopTools_MapIteratorOfMapOfShape itm(MapFac);
107 if (MapFac.Extent() <= 1) { // un seul plan. Rien a faire
108 if (MapFac.Extent() == 1) {
109 myMap(edgpr).Append(itm.Key());
110 goodfaces.Append(itm.Key());
115 while (MapFac.Extent() >= 2) {
117 TopTools_ListOfShape FacFuse;
118 TopoDS_Face FaceRef = TopoDS::Face(itm.Key());
119 FacFuse.Append(FaceRef);
120 Handle(Geom_Surface) P = BRep_Tool::Surface(FaceRef);
121 if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
122 P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
124 gp_Pln Plref = Handle(Geom_Plane)::DownCast(P)->Pln();
126 for (itm.Next(); itm.More(); itm.Next()) {
127 P = BRep_Tool::Surface(TopoDS::Face(itm.Key()));
128 if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
129 P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
131 gp_Pln Pl = Handle(Geom_Plane)::DownCast(P)->Pln();
132 if (Pl.Axis().IsParallel(Plref.Axis(),Precision::Angular()) &&
133 Plref.Contains(Pl.Location(),Precision::Confusion())) {
134 FacFuse.Append(itm.Key());
138 // FacFuse contient des faces de meme support. Il faut en faire
139 // des composantes connexes
141 while (FacFuse.Extent() >= 2) {
142 FaceRef = TopoDS::Face(FacFuse.First());
143 // Recuperer l'orientation
144 TopAbs_Orientation orref = Orientation(FaceRef,Result);
145 P = BRep_Tool::Surface(FaceRef);
146 if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
147 P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
149 Plref = Handle(Geom_Plane)::DownCast(P)->Pln();
150 gp_Dir Dirref(Plref.Axis().Direction());
151 if ((Plref.Direct() && orref == TopAbs_REVERSED) ||
152 (!Plref.Direct() && orref == TopAbs_FORWARD)) {
156 TopTools_MapOfShape MapEd;
157 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
158 exp.More(); exp.Next()) {
159 MapEd.Add(exp.Current());
162 MapFac.Remove(FaceRef);
163 FacFuse.RemoveFirst(); // on enleve FaceRef
164 Standard_Boolean FaceToFuse = Standard_False;
165 Standard_Boolean MoreFound;
169 MoreFound = Standard_False;
170 for (it.Initialize(FacFuse); it.More(); it.Next()) {
171 for (exp.Init(it.Value(),TopAbs_EDGE);
172 exp.More(); exp.Next()) {
173 if (MapEd.Contains(exp.Current())) {
174 FaceToFuse = Standard_True;
175 MoreFound = Standard_True;
184 const TopoDS_Face& fac = TopoDS::Face(it.Value());
185 TopAbs_Orientation orrelat = Orientation(fac,Result);
186 Handle(Geom_Surface) OtherP = BRep_Tool::Surface(fac);
187 if (OtherP->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
188 OtherP = Handle(Geom_RectangularTrimmedSurface)::
189 DownCast(OtherP)->BasisSurface();
191 gp_Pln Pl = Handle(Geom_Plane)::DownCast(OtherP)->Pln();
192 gp_Dir Dirpl(Pl.Axis().Direction());
193 if ((Pl.Direct() && orrelat == TopAbs_REVERSED) ||
194 (!Plref.Direct() && orrelat == TopAbs_FORWARD)) {
197 if (Dirpl.Dot(Dirref) > 0) {
198 orrelat = TopAbs_FORWARD;
201 orrelat = TopAbs_REVERSED;
203 for (exp.Init(fac.Oriented(orrelat),TopAbs_EDGE);
204 exp.More(); exp.Next()) {
205 if (!MapEd.Add(exp.Current())) {
206 MapEd.Remove(exp.Current());
217 B.MakeFace(NewFace,P,BRep_Tool::Tolerance(FaceRef));
220 for (TopTools_MapIteratorOfMapOfShape itm2(MapEd);
221 itm2.More(); itm2.Next()) {
222 B.Add(NewWire,itm2.Key());
224 exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
225 NewWire.Orientation(exp.Current().Orientation());
226 B.Add(NewFace,NewWire);
227 myMap(edgpr).Append(NewFace);
228 goodfaces.Append(NewFace);
231 if (FacFuse.Extent() == 1) {
232 MapFac.Remove(FacFuse.First());
233 myMap(edgpr).Append(FacFuse.First());
234 goodfaces.Append(FacFuse.First());
240 for (exp.Init(myPipe.FirstShape(),TopAbs_FACE); exp.More(); exp.Next()) {
241 goodfaces.Append(exp.Current());
243 for (exp.Init(myPipe.LastShape(),TopAbs_FACE); exp.More(); exp.Next()) {
244 goodfaces.Append(exp.Current());
247 LocOpe_BuildShape BS(goodfaces);
252 //=======================================================================
255 //=======================================================================
257 const TopoDS_Shape& LocOpe_Pipe::Shape () const
263 //=======================================================================
266 //=======================================================================
268 const TopTools_ListOfShape& LocOpe_Pipe::Shapes (const TopoDS_Shape& S)
270 TopAbs_ShapeEnum typS = S.ShapeType();
271 if (typS != TopAbs_EDGE && typS != TopAbs_VERTEX) {
272 throw Standard_DomainError();
274 // for (TopExp_Explorer exp(myPipe.Profile(),typS); exp.More(); exp.Next()) {
275 TopExp_Explorer exp(myPipe.Profile(),typS) ;
276 for ( ; exp.More(); exp.Next()) {
277 if (exp.Current().IsSame(S)) {
282 throw Standard_NoSuchObject();
286 if (typS == TopAbs_VERTEX) {
287 const TopoDS_Vertex& VProfile = TopoDS::Vertex(S);
288 for (exp.Init(myPipe.Spine(),TopAbs_EDGE); exp.More(); exp.Next()) {
289 const TopoDS_Edge& edsp = TopoDS::Edge(exp.Current());
290 TopoDS_Edge resed = myPipe.Edge(edsp,VProfile);
291 if (!resed.IsNull()) {
292 myGShap.Append(resed);
298 const TopoDS_Edge& EProfile = TopoDS::Edge(S);
299 return myMap(EProfile);
303 //=======================================================================
304 //function : GetCurves
306 //=======================================================================
308 const TColGeom_SequenceOfCurve&
309 LocOpe_Pipe::Curves(const TColgp_SequenceOfPnt& Spt)
313 TopTools_MapOfShape Map;
315 Standard_Integer i , j , k , Nbpnt = Spt.Length();
319 for ( i = 1; i <= Nbpnt; i++) {
321 Standard_Integer MaxDeg = 0;
322 TColGeom_SequenceOfCurve seq;
323 TopoDS_Wire W = myPipe.PipeLine(P1);
325 TopExp_Explorer ex(W, TopAbs_EDGE);
326 for (; ex.More(); ex.Next()) {
327 Handle(Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(ex.Current()), p1, p2);
328 Handle(Geom_BSplineCurve) C = GeomConvert::CurveToBSplineCurve (C1);
332 MaxDeg = Max(MaxDeg,C->Degree());
334 if (p1 != C->FirstParameter() || p2 != C->LastParameter()) {
337 Standard_Integer Nbkn = C->NbKnots();
338 TColStd_Array1OfReal Tkn(1,Nbkn);
340 BSplCLib::Reparametrize(seq.Length(),seq.Length()+1,Tkn);
345 Handle(Geom_Curve) newC;
346 Standard_Integer Nbkn=0 ,Nbp=0;
347 Standard_Integer Nbcurv = seq.Length();
353 Handle(Geom_BSplineCurve) Bsp;
354 for (j=1; j<=Nbcurv; j++) {
355 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
356 Bsp->IncreaseDegree(MaxDeg);
357 Nbp += Bsp->NbPoles();
358 Nbkn += Bsp->NbKnots();
362 TColStd_Array1OfReal Tkn(1,Nbkn);
363 TColStd_Array1OfInteger Tmu(1,Nbkn);
364 TColgp_Array1OfPnt Tpol(1,Nbp);
365 Standard_Integer Ik=0,Ip=0;
367 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(1));
368 for ( k = 1; k<= Bsp->NbPoles(); k++) {
370 Tpol(Ip) = Bsp->Pole(k);
372 for (k = 1; k<= Bsp->NbKnots(); k++) {
374 Tkn(Ik) = Bsp->Knot(k);
375 Tmu(Ik) = Bsp->Multiplicity(k);
379 for (j=2; j<=Nbcurv; j++) {
380 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
381 for (k = 2; k<= Bsp->NbPoles(); k++) {
383 Tpol(Ip) = Bsp->Pole(k);
385 for (k = 2; k<= Bsp->NbKnots(); k++) {
387 Tkn(Ik) = Bsp->Knot(k);
388 Tmu(Ik) = Bsp->Multiplicity(k);
393 newC = new Geom_BSplineCurve(Tpol,Tkn,Tmu,MaxDeg);
401 //=======================================================================
402 //function : Orientation
403 //purpose : static, not member
404 //=======================================================================
406 static TopAbs_Orientation Orientation(const TopoDS_Shape& Sub,
407 const TopoDS_Shape& S)
410 for (exp.Init(S,Sub.ShapeType()); exp.More(); exp.Next()) {
411 if (exp.Current().IsSame(Sub)) {
412 return exp.Current().Orientation();
415 throw Standard_NoSuchObject();
419 //=======================================================================
420 //function : BarycCurve
422 //=======================================================================
424 Handle(Geom_Curve) LocOpe_Pipe::BarycCurve()
426 Standard_Integer j , k ;
428 gp_Pnt bar(0., 0., 0.);
429 TColgp_SequenceOfPnt spt;
430 TopoDS_Shape Base = FirstShape();
431 LocOpe::SampleEdges(Base, spt);
432 for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
433 const gp_Pnt& pvt = spt(jj);
434 bar.ChangeCoord() += pvt.XYZ();
436 bar.ChangeCoord().Divide(spt.Length());
442 Standard_Integer MaxDeg = 0;
443 TColGeom_SequenceOfCurve seq;
444 TopoDS_Wire W = myPipe.PipeLine(P1);
446 TopExp_Explorer ex(W, TopAbs_EDGE);
447 for (; ex.More(); ex.Next()) {
448 Handle(Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(ex.Current()), p1, p2);
449 Handle(Geom_BSplineCurve) C = GeomConvert::CurveToBSplineCurve (C1);
454 MaxDeg = Max(MaxDeg,C->Degree());
456 if (p1 != C->FirstParameter() || p2 != C->LastParameter()) {
459 Standard_Integer Nbkn = C->NbKnots();
460 TColStd_Array1OfReal Tkn(1,Nbkn);
462 BSplCLib::Reparametrize(seq.Length(),seq.Length()+1,Tkn);
466 Handle(Geom_Curve) newC;
467 Standard_Integer Nbkn=0 ,Nbp=0;
468 Standard_Integer Nbcurv = seq.Length();
472 Handle(Geom_BSplineCurve) Bsp;
473 for ( j=1; j<=Nbcurv; j++) {
474 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
475 Bsp->IncreaseDegree(MaxDeg);
476 Nbp += Bsp->NbPoles();
477 Nbkn += Bsp->NbKnots();
481 TColStd_Array1OfReal Tkn(1,Nbkn);
482 TColStd_Array1OfInteger Tmu(1,Nbkn);
483 TColgp_Array1OfPnt Tpol(1,Nbp);
484 Standard_Integer Ik=0,Ip=0;
486 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(1));
487 for ( k = 1; k<= Bsp->NbPoles(); k++) {
489 Tpol(Ip) = Bsp->Pole(k);
491 for (k = 1; k<= Bsp->NbKnots(); k++) {
493 Tkn(Ik) = Bsp->Knot(k);
494 Tmu(Ik) = Bsp->Multiplicity(k);
498 for (j=2; j<=Nbcurv; j++) {
499 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
500 for (k = 2; k<= Bsp->NbPoles(); k++) {
502 Tpol(Ip) = Bsp->Pole(k);
504 for (k = 2; k<= Bsp->NbKnots(); k++) {
506 Tkn(Ik) = Bsp->Knot(k);
507 Tmu(Ik) = Bsp->Multiplicity(k);
512 newC = new Geom_BSplineCurve(Tpol,Tkn,Tmu,MaxDeg);