1 // Created on: 1994-10-04
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-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.
17 #include <BRepMAT2d_Explorer.ixx>
18 #include <MAT2d_SequenceOfSequenceOfCurve.hxx>
19 #include <TColGeom2d_SequenceOfCurve.hxx>
20 #include <TopoDS_Wire.hxx>
21 #include <BRepTools_WireExplorer.hxx>
22 #include <TopLoc_Location.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_TrimmedCurve.hxx>
25 #include <Geom2d_TrimmedCurve.hxx>
26 #include <GeomAPI.hxx>
27 #include <BRep_Tool.hxx>
30 #include <TopExp_Explorer.hxx>
34 #include <Precision.hxx>
35 #include <Geom2d_BSplineCurve.hxx>
36 #include <Geom2dConvert.hxx>
37 #include <BRepBuilderAPI_MakeFace.hxx>
39 #include <BRep_Builder.hxx>
40 #include <BRepLib.hxx>
41 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
42 #include <GeomAbs_CurveType.hxx>
43 #include <Geom2d_Circle.hxx>
44 #include <Geom2d_Line.hxx>
45 #include <Geom2d_Ellipse.hxx>
46 #include <Geom2d_Parabola.hxx>
47 #include <Geom2d_Hyperbola.hxx>
48 #include <Geom2d_BezierCurve.hxx>
49 #include <GCE2d_MakeArcOfCircle.hxx>
50 #include <GCE2d_MakeSegment.hxx>
52 // Modified by Sergey KHROMOV - Thu Dec 5 10:38:14 2002 Begin
53 static TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve,
54 const TopoDS_Face &theFace,
55 const TopoDS_Vertex &theVFirst,
56 const TopoDS_Vertex &theVLast);
57 // Modified by Sergey KHROMOV - Thu Dec 5 10:38:16 2002 End
59 static GeomAbs_CurveType GetCurveType(const Handle(Geom2d_Curve)& theC2d);
60 static void AdjustCurveEnd(Handle(Geom2d_BoundedCurve)& theC2d, const gp_Pnt2d theP,
61 const Standard_Boolean isFirst);
63 //=======================================================================
64 //function : BRepMAT2d_Explorer
66 //=======================================================================
68 BRepMAT2d_Explorer::BRepMAT2d_Explorer()
73 //=======================================================================
74 //function : BRepMAT2d_Explorer
76 //=======================================================================
78 BRepMAT2d_Explorer::BRepMAT2d_Explorer(const TopoDS_Face& aFace)
83 //=======================================================================
86 //=======================================================================
88 void BRepMAT2d_Explorer::Perform(const TopoDS_Face& aFace)
92 TopoDS_Face F = TopoDS::Face(aFace);
93 F.Orientation(TopAbs_FORWARD);
94 TopExp_Explorer Exp (F,TopAbs_WIRE);
95 // Modified by Sergey KHROMOV - Tue Nov 26 16:10:37 2002 Begin
96 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
97 TopoDS_Face aNewF = BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion());
100 Add (TopoDS::Wire (Exp.Current()),F, aNewF);
104 BRepLib::BuildCurves3d(aNewF);
106 myModifShapes.Add(aFace, aNewF);
107 // CheckConnection();
108 // Modified by Sergey KHROMOV - Tue Nov 26 16:10:38 2002 End
111 //=======================================================================
114 //=======================================================================
116 void BRepMAT2d_Explorer::Add(const TopoDS_Wire& Spine,
117 const TopoDS_Face& aFace,
118 TopoDS_Face& aNewFace)
120 // Modified by Sergey KHROMOV - Tue Nov 26 14:25:46 2002 Begin
121 // This method is totally rewroted to include check
122 // of connection and creation of a new spine.
124 myIsClosed(currentContour) = (Spine.Closed()) ? Standard_True : Standard_False;
126 // Modified by skv - Wed Jun 23 12:23:01 2004 Integration Begin
127 // Taking into account side of bisecting loci construction.
128 // TopoDS_Wire aWFwd = TopoDS::Wire(Spine.Oriented(TopAbs_FORWARD));
129 // BRepTools_WireExplorer anExp(aWFwd, aFace);
130 BRepTools_WireExplorer anExp(Spine, aFace);
131 // Modified by skv - Wed Jun 23 12:23:02 2004 Integration End
132 TopTools_IndexedDataMapOfShapeShape anOldNewE;
137 TopoDS_Edge aFirstEdge = anExp.Current();
138 TopoDS_Edge aPrevEdge = aFirstEdge;
139 Standard_Real UFirst,ULast, aD;
140 Handle(Geom2d_Curve) C2d;
141 Handle(Geom2d_TrimmedCurve) CT2d;
142 Handle(Geom2d_TrimmedCurve) aFirstCurve;
146 // Modified by skv - Mon Jul 11 19:00:25 2005 Integration Begin
147 // Set the confusion tolerance in accordance with the further algo
148 // Standard_Real aTolConf = Precision::Confusion();
149 Standard_Real aTolConf = 1.e-8;
150 // Modified by skv - Mon Jul 11 19:00:25 2005 Integration End
151 Standard_Boolean isModif = Standard_False;
153 // Treatment of the first edge of a wire.
154 anOldNewE.Add(aFirstEdge, aFirstEdge);
155 C2d = BRep_Tool::CurveOnSurface (aFirstEdge, aFace, UFirst, ULast);
156 CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast);
158 if (aFirstEdge.Orientation() == TopAbs_REVERSED)
161 aPFirst = CT2d->Value(CT2d->FirstParameter());
162 aPLast = CT2d->Value(CT2d->LastParameter());
168 // Treatment of the next edges:
169 for (; anExp.More(); anExp.Next()) {
170 TopoDS_Edge anEdge = anExp.Current();
172 anOldNewE.Add(anEdge, anEdge);
173 C2d = BRep_Tool::CurveOnSurface (anEdge, aFace, UFirst, ULast);
174 CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast);
176 if (anEdge.Orientation() == TopAbs_REVERSED)
179 aPCurFirst = CT2d->Value(CT2d->FirstParameter());
181 aD=aPLast.Distance(aPCurFirst);
183 // There are two ways how to fill holes:
184 // First, to create a line between these two points.
185 // Second, create a BSpline curve and to add the last point of the previous
186 // curve as the first pole of the current one. Second method which
187 // is worse was performed before and leaved here. Otherwise too much
188 // code should be rewritten.
189 isModif = Standard_True;
191 Standard_Integer aNbC = theCurves.Value(currentContour).Length();
192 Handle(Geom2d_BoundedCurve) CPrev =
193 Handle(Geom2d_BoundedCurve)::DownCast(theCurves.ChangeValue(currentContour).ChangeValue(aNbC));
195 GeomAbs_CurveType TCPrev = GetCurveType(CPrev);
196 GeomAbs_CurveType TCCurr = GetCurveType(CT2d);
200 AdjustCurveEnd(CT2d, aPLast, Standard_True);
201 // Creation of new edge.
202 TopoDS_Edge aNewEdge;
203 TopoDS_Vertex aVf = TopExp::FirstVertex(anEdge);
204 TopoDS_Vertex aVl = TopExp::LastVertex(anEdge);
206 if (anEdge.Orientation() == TopAbs_FORWARD)
207 aNewEdge = MakeEdge(CT2d, aNewFace, aVf, aVl);
209 aNewEdge = MakeEdge(CT2d->Reversed(), aNewFace, aVf, aVl);
211 aNewEdge.Orientation(anEdge.Orientation());
213 anOldNewE.ChangeFromKey(anEdge) = aNewEdge;
217 gp_Pnt2d aP = CT2d->Value(CT2d->FirstParameter());
218 AdjustCurveEnd(CPrev, aP, Standard_False);
219 theCurves.ChangeValue(currentContour).ChangeValue(aNbC) = CPrev;
220 //Change previous edge
221 TopoDS_Edge aNewEdge;
222 TopoDS_Vertex aVf = TopExp::FirstVertex(aPrevEdge);
223 TopoDS_Vertex aVl = TopExp::LastVertex(aPrevEdge);
225 if (aPrevEdge.Orientation() == TopAbs_FORWARD)
226 aNewEdge = MakeEdge(CPrev, aNewFace, aVf, aVl);
228 aNewEdge = MakeEdge(CPrev->Reversed(), aNewFace, aVf, aVl);
230 aNewEdge.Orientation(aPrevEdge.Orientation());
232 anOldNewE.ChangeFromKey(aPrevEdge) = aNewEdge;
238 aPLast = CT2d->Value(CT2d->LastParameter());
243 // Check of the distance between the first and the last point of wire
244 // if the wire is closed.
245 if (myIsClosed(currentContour) && aPLast.Distance(aPFirst) > aTolConf) {
246 isModif = Standard_True;
249 Standard_Integer aNbC = theCurves.Value(currentContour).Length();
250 Handle(Geom2d_BoundedCurve) CPrev =
251 Handle(Geom2d_BoundedCurve)::DownCast(theCurves.ChangeValue(currentContour).ChangeValue(aNbC));
253 GeomAbs_CurveType TCPrev = GetCurveType(CPrev);
254 GeomAbs_CurveType TCCurr = GetCurveType(aFirstCurve);
258 AdjustCurveEnd(aFirstCurve, aPLast, Standard_True);
259 theCurves.ChangeValue(currentContour).ChangeValue(1) = aFirstCurve;
260 // Creation of new edge.
261 TopoDS_Edge aNewEdge;
262 TopoDS_Vertex aVf = TopExp::FirstVertex(aFirstEdge);
263 TopoDS_Vertex aVl = TopExp::LastVertex(aFirstEdge);
265 if (aFirstEdge.Orientation() == TopAbs_FORWARD)
266 aNewEdge = MakeEdge(aFirstCurve, aNewFace, aVf, aVl);
268 aNewEdge = MakeEdge(aFirstCurve->Reversed(), aNewFace, aVf, aVl);
270 aNewEdge.Orientation(aFirstEdge.Orientation());
272 anOldNewE.ChangeFromKey(aFirstEdge) = aNewEdge;
276 gp_Pnt2d aP = aFirstCurve->Value(aFirstCurve->FirstParameter());
277 AdjustCurveEnd(CPrev, aP, Standard_False);
278 theCurves.ChangeValue(currentContour).ChangeValue(aNbC) = CPrev;
279 //Change previous edge
280 TopoDS_Edge aNewEdge;
281 TopoDS_Vertex aVf = TopExp::FirstVertex(aPrevEdge);
282 TopoDS_Vertex aVl = TopExp::LastVertex(aPrevEdge);
284 if (aPrevEdge.Orientation() == TopAbs_FORWARD)
285 aNewEdge = MakeEdge(CPrev, aNewFace, aVf, aVl);
287 aNewEdge = MakeEdge(CPrev->Reversed(), aNewFace, aVf, aVl);
289 aNewEdge.Orientation(aPrevEdge.Orientation());
291 anOldNewE.ChangeFromKey(aPrevEdge) = aNewEdge;
297 TopoDS_Wire aNewWire;
298 BRep_Builder aBuilder;
302 Standard_Integer aNbEdges = anOldNewE.Extent();
304 aBuilder.MakeWire(aNewWire);
306 for (i = 1; i <= aNbEdges; i++) {
307 const TopoDS_Shape &aKey = anOldNewE.FindKey(i);
308 const TopoDS_Shape &aNewEdge = anOldNewE.FindFromIndex(i);
310 aBuilder.Add(aNewWire, aNewEdge);
311 myModifShapes.Add(aKey, aNewEdge);
314 if (myIsClosed(currentContour))
315 aNewWire.Closed(Standard_True);
317 // Modified by skv - Fri Nov 12 17:22:12 2004 Integration Begin
318 // The orientation of wire is already taken into account.
319 // aNewWire.Orientation(Spine.Orientation());
320 // Modified by skv - Fri Nov 12 17:22:12 2004 Integration End
321 myModifShapes.Add(Spine, aNewWire);
325 aBuilder.Add(aNewFace, aNewWire);
326 // Modified by Sergey KHROMOV - Tue Nov 26 14:25:53 2002 End
329 //=======================================================================
330 //function : CheckConnection
332 //=======================================================================
334 // Modified by Sergey KHROMOV - Tue Nov 26 17:21:44 2002 Begin
335 // void BRepMAT2d_Explorer::CheckConnection()
337 // for (Standard_Integer i = 1; i <= theCurves.Length(); i++)
338 // for (Standard_Integer j = 2; j <= theCurves(i).Length(); j++)
340 // gp_Pnt2d P1 = theCurves(i)(j-1)->Value( theCurves(i)(j-1)->LastParameter() );
341 // gp_Pnt2d P2 = theCurves(i)(j)->Value( theCurves(i)(j)->FirstParameter() );
342 // if (P1.Distance( P2 ) > Precision::Confusion())
344 // Handle( Geom2d_BSplineCurve ) BCurve;
345 // if (theCurves(i)(j)->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
346 // BCurve = Geom2dConvert::CurveToBSplineCurve( theCurves(i)(j) );
348 // BCurve = Handle( Geom2d_BSplineCurve )::DownCast( theCurves(i)(j) );
349 // BCurve->SetPole( 1, P1 );
350 // theCurves(i)(j) = new Geom2d_TrimmedCurve( BCurve, BCurve->FirstParameter(), BCurve->LastParameter() );
354 // Modified by Sergey KHROMOV - Tue Nov 26 17:21:29 2002 End
356 //=======================================================================
359 //=======================================================================
361 void BRepMAT2d_Explorer::Clear()
365 // Modified by Sergey KHROMOV - Wed Mar 6 16:07:55 2002 Begin
367 myModifShapes.Clear();
368 // Modified by Sergey KHROMOV - Wed Mar 6 16:07:55 2002 End
372 //=======================================================================
373 //function : NewContour
375 //=======================================================================
377 void BRepMAT2d_Explorer::NewContour()
379 TColGeom2d_SequenceOfCurve Contour;
380 theCurves.Append(Contour);
381 // Modified by Sergey KHROMOV - Wed Mar 6 16:12:05 2002 Begin
382 myIsClosed.Append(Standard_False);
383 // Modified by Sergey KHROMOV - Wed Mar 6 16:12:05 2002 End
388 //=======================================================================
391 //=======================================================================
393 void BRepMAT2d_Explorer::Add(const Handle(Geom2d_Curve)& aCurve)
395 theCurves.ChangeValue(currentContour).Append(aCurve);
398 //=======================================================================
399 //function : NumberOfContours
401 //=======================================================================
403 Standard_Integer BRepMAT2d_Explorer::NumberOfContours() const
405 return theCurves.Length() ;
409 //=======================================================================
410 //function : NumberOfCurves
412 //=======================================================================
414 Standard_Integer BRepMAT2d_Explorer::NumberOfCurves
415 (const Standard_Integer IndexContour)
418 return theCurves.Value(IndexContour).Length();
422 //=======================================================================
425 //=======================================================================
427 void BRepMAT2d_Explorer::Init(const Standard_Integer IndexContour)
429 currentContour = IndexContour;
434 //=======================================================================
437 //=======================================================================
439 Standard_Boolean BRepMAT2d_Explorer::More() const
441 return (current <= NumberOfCurves(currentContour));
445 //=======================================================================
448 //=======================================================================
450 void BRepMAT2d_Explorer::Next()
456 //=======================================================================
459 //=======================================================================
461 Handle(Geom2d_Curve) BRepMAT2d_Explorer::Value() const
463 return theCurves.Value(currentContour).Value(current);
466 //=======================================================================
469 //=======================================================================
471 TopoDS_Shape BRepMAT2d_Explorer::Shape() const
477 //=======================================================================
480 //=======================================================================
482 const TColGeom2d_SequenceOfCurve& BRepMAT2d_Explorer::Contour
483 (const Standard_Integer IC)
486 return theCurves.Value(IC);
490 // Modified by Sergey KHROMOV - Wed Mar 6 17:40:07 2002 Begin
491 //=======================================================================
492 //function : IsModified
494 //=======================================================================
496 Standard_Boolean BRepMAT2d_Explorer::IsModified
497 (const TopoDS_Shape &aShape) const
499 if (myModifShapes.Contains(aShape)) {
500 const TopoDS_Shape &aNewShape = myModifShapes.FindFromKey(aShape);
501 const Standard_Boolean isSame = aNewShape.IsSame(aShape);
506 return Standard_False;
509 //=======================================================================
510 //function : ModifiedShape
512 //=======================================================================
514 TopoDS_Shape BRepMAT2d_Explorer::ModifiedShape
515 (const TopoDS_Shape &aShape) const
517 if (myModifShapes.Contains(aShape)) {
518 const TopoDS_Shape &aNewShape = myModifShapes.FindFromKey(aShape);
526 //=======================================================================
527 //function : GetIsClosed
529 //=======================================================================
531 const TColStd_SequenceOfBoolean &BRepMAT2d_Explorer::GetIsClosed() const
536 //=======================================================================
537 //function : MakeEdge
538 //purpose : Creation of an edge by 2d curve, face and two vertices.
539 //=======================================================================
541 TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve,
542 const TopoDS_Face &theFace,
543 const TopoDS_Vertex &theVFirst,
544 const TopoDS_Vertex &theVLast)
546 TopoDS_Edge aNewEdge;
547 BRep_Builder aBuilder;
548 Standard_Real aTol = Precision::Confusion();
549 Standard_Real aFPar = theCurve->FirstParameter();
550 Standard_Real aLPar = theCurve->LastParameter();
552 aBuilder.MakeEdge(aNewEdge);
553 aBuilder.UpdateEdge(aNewEdge, theCurve, theFace, aTol);
554 aBuilder.Add(aNewEdge, theVFirst.Oriented(TopAbs_FORWARD));
555 aBuilder.Add(aNewEdge, theVLast.Oriented(TopAbs_REVERSED));
556 aBuilder.Range(aNewEdge, aFPar, aLPar);
560 // Modified by Sergey KHROMOV - Wed Mar 6 17:40:14 2002 End
562 //=======================================================================
563 //function : GetCurveType
564 //purpose : Get curve type.
565 //=======================================================================
567 GeomAbs_CurveType GetCurveType(const Handle(Geom2d_Curve)& theC2d)
569 GeomAbs_CurveType aTypeCurve = GeomAbs_OtherCurve;
570 Handle(Standard_Type) TheType = theC2d->DynamicType();
571 if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
572 TheType = (*((Handle(Geom2d_TrimmedCurve)*)&theC2d))->BasisCurve()->DynamicType();
575 if ( TheType == STANDARD_TYPE(Geom2d_Circle)) {
576 aTypeCurve = GeomAbs_Circle;
578 else if ( TheType ==STANDARD_TYPE(Geom2d_Line)) {
579 aTypeCurve = GeomAbs_Line;
581 else if ( TheType == STANDARD_TYPE(Geom2d_Ellipse)) {
582 aTypeCurve = GeomAbs_Ellipse;
584 else if ( TheType == STANDARD_TYPE(Geom2d_Parabola)) {
585 aTypeCurve = GeomAbs_Parabola;
587 else if ( TheType == STANDARD_TYPE(Geom2d_Hyperbola)) {
588 aTypeCurve = GeomAbs_Hyperbola;
590 else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) {
591 aTypeCurve = GeomAbs_BezierCurve;
593 else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
594 aTypeCurve = GeomAbs_BSplineCurve;
597 aTypeCurve = GeomAbs_OtherCurve;
601 //=======================================================================
602 //function : AdjustCurveEnd
604 //=======================================================================
605 void AdjustCurveEnd(Handle(Geom2d_BoundedCurve)& theC2d, const gp_Pnt2d theP,
606 const Standard_Boolean isFirst)
608 GeomAbs_CurveType aType = GetCurveType(theC2d);
609 if(aType == GeomAbs_Line)
614 gp_Pnt2d aP = theC2d->Value(theC2d->LastParameter());
615 theC2d = GCE2d_MakeSegment(theP, aP);
619 gp_Pnt2d aP = theC2d->Value(theC2d->FirstParameter());
620 theC2d = GCE2d_MakeSegment(aP, theP);
625 //Convert to BSpline and adjust first pole
626 Handle(Geom2d_BSplineCurve) BCurve =
627 Geom2dConvert::CurveToBSplineCurve(theC2d, Convert_QuasiAngular);
630 BCurve->SetPole(1, theP);
631 theC2d = new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(),
632 BCurve->LastParameter());
636 BCurve->SetPole(BCurve->NbPoles(), theP);
637 theC2d = new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(),
638 BCurve->LastParameter());