1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <ShapeUpgrade_RemoveLocations.ixx>
15 #include <TopAbs_ShapeEnum.hxx>
16 #include <TopLoc_Location.hxx>
17 #include <TopoDS_Face.hxx>
19 #include <Geom_Surface.hxx>
20 #include <BRep_Builder.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Vertex.hxx>
25 #include <Geom_Curve.hxx>
26 #include <BRep_Tool.hxx>
28 #include <TopoDS_Iterator.hxx>
29 #include <TopTools_DataMapOfShapeShape.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom_Geometry.hxx>
32 #include <gp_Trsf.hxx>
34 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
35 #include <BRep_TEdge.hxx>
36 #include <BRep_GCurve.hxx>
37 #include <BRep_CurveRepresentation.hxx>
38 #include <TColStd_ListIteratorOfListOfTransient.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TColStd_ListOfTransient.hxx>
41 //#include <ShapeUpgrade_DataMapOfShapeListOfTransient.hxx>
42 #include <ShapeBuild_Edge.hxx>
43 #include <Geom_Plane.hxx>
45 //=======================================================================
46 //function : ShapeUpgrade_RemoveLocations
48 //=======================================================================
50 ShapeUpgrade_RemoveLocations::ShapeUpgrade_RemoveLocations()
52 myLevelRemoving = TopAbs_SHAPE;
55 //=======================================================================
58 //=======================================================================
60 Standard_Boolean ShapeUpgrade_RemoveLocations::Remove(const TopoDS_Shape& theShape)
62 TopoDS_Shape aShape = theShape;
64 TopAbs_ShapeEnum shtype = theShape.ShapeType();
65 Standard_Boolean isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) ||
66 ((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype)));
68 Standard_Boolean isDone = MakeNewShape(theShape,S,myShape,isRemoveLoc);
74 //=======================================================================
75 //function : RebuildShape
77 //=======================================================================
78 static Standard_Boolean RebuildShape(const TopoDS_Face& theFace, TopoDS_Face& theNewFace)
82 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace,aLoc);
83 Standard_Boolean isRebuild = Standard_False;
84 if(!aLoc.IsIdentity()) {
85 Handle(Geom_Surface) anewSurf =Handle(Geom_Surface)::DownCast( aSurf->Transformed(aLoc.Transformation()));
86 aB.MakeFace(theNewFace,anewSurf,BRep_Tool::Tolerance(theFace));
87 isRebuild = Standard_True;
91 //=======================================================================
92 //function : RebuildShape
94 //=======================================================================
95 static Standard_Boolean RebuildShape(const TopoDS_Edge& theEdge, TopoDS_Edge& theNewEdge,
96 const TopoDS_Face& theFace, TopoDS_Face& theNewFace,
97 Standard_Boolean isBound)
99 Standard_Boolean isRebuild = Standard_False;
102 Handle(Geom_Curve) C3d;
103 TopLoc_Location aLoc;
104 Standard_Real First3d,Last3d;
105 C3d = BRep_Tool::Curve( theEdge,aLoc,First3d,Last3d);
106 aB.MakeEdge(theNewEdge);
108 if(!aLoc.IsIdentity()) {
109 Handle(Geom_Curve) anewC3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(aLoc.Transformation()));
113 aB.UpdateEdge(theNewEdge,C3d,BRep_Tool::Tolerance(theEdge));
114 aB.Range(theNewEdge,First3d,Last3d);
116 theNewEdge.Orientation(theEdge.Orientation());
117 if(BRep_Tool::Degenerated(theEdge))
118 aB.Degenerated(theNewEdge,Standard_True);
119 isRebuild = Standard_True;
121 if(!theFace.IsNull()) {
122 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
123 if(!aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
124 Handle(Geom2d_Curve) c2d,c2d1;
125 Standard_Real First2d,Last2d;
127 c2d= BRep_Tool::CurveOnSurface( theEdge,theFace,First2d,Last2d);
128 if(BRep_Tool::IsClosed(theEdge,theFace)) {
129 if(!BRep_Tool::IsClosed(theNewEdge,theNewFace)) {
130 TopoDS_Edge tmpE = TopoDS::Edge(theEdge.Reversed());
131 c2d1= BRep_Tool::CurveOnSurface(tmpE,theFace,First2d,Last2d);
132 TopAbs_Orientation OrEdge = theNewEdge.Orientation();
134 if(theFace.Orientation() == TopAbs_REVERSED)
135 OrEdge = ( OrEdge == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
137 if(OrEdge == TopAbs_FORWARD)
138 aB.UpdateEdge(theNewEdge,c2d, c2d1,theNewFace,0);
139 else aB.UpdateEdge(theNewEdge,c2d1, c2d,theNewFace,0);
144 aB.UpdateEdge(theNewEdge,c2d,theNewFace,0);
146 if(!c2d.IsNull() || !c2d1.IsNull())
147 aB.Range(theNewEdge,theNewFace,First2d,Last2d);
152 //=======================================================================
153 //function : RebuildShape
155 //=======================================================================
156 static Standard_Boolean RebuildShape(const TopoDS_Vertex& theVertex, TopoDS_Vertex& theNewVertex)
159 aB.MakeVertex(theNewVertex);
160 theNewVertex.Orientation( theVertex.Orientation());
161 gp_Pnt p1 = BRep_Tool::Pnt( theVertex);
162 aB.UpdateVertex(theNewVertex,p1,BRep_Tool::Tolerance( theVertex));
163 return Standard_True;
165 //=======================================================================
166 //function : MakeNewShape
168 //=======================================================================
170 Standard_Boolean ShapeUpgrade_RemoveLocations::MakeNewShape(const TopoDS_Shape& theShape,
171 const TopoDS_Shape& theAncShape,
172 TopoDS_Shape& theNewShape,
173 const Standard_Boolean theRemoveLoc)
175 Standard_Boolean isDone = Standard_False;
176 TopoDS_Shape aNewShape;
177 TopAbs_ShapeEnum shtype = theShape.ShapeType();
179 TopoDS_Shape aShape = theShape;
180 if(!theRemoveLoc && !theShape.Location().IsIdentity()) {
181 TopLoc_Location nulLoc;
182 aShape.Location(nulLoc);
184 Standard_Boolean isBound = myMapNewShapes.IsBound(aShape);
186 aNewShape= myMapNewShapes.Find(aShape);
187 aNewShape.Orientation(theShape.Orientation());
188 if(!theRemoveLoc && !theShape.Location().IsIdentity()) {
189 TopLoc_Location aL = theShape.Location();
190 aNewShape.Location(aL);
192 if(shtype != TopAbs_EDGE) {
194 theNewShape = aNewShape;
196 return Standard_True;
201 Standard_Boolean isRemoveLoc = theRemoveLoc;
203 isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) ||
204 ((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype)));
207 Standard_Boolean aRebuild = Standard_False;
208 TopoDS_Shape anAncShape = theAncShape;
209 if(shtype == TopAbs_FACE)
211 if(isRemoveLoc && (!aShape.Location().IsIdentity() || shtype == TopAbs_EDGE || shtype == TopAbs_FACE )) {
213 //Rebuild geometry for shape with location.
214 if(shtype == TopAbs_FACE) {
215 TopoDS_Face anewFace;
216 TopoDS_Face oldFace = TopoDS::Face(aShape);
217 aRebuild = RebuildShape(oldFace,anewFace);
219 aNewShape = anewFace;
220 myMapNewShapes.Bind(oldFace,aNewShape);
224 else if(shtype == TopAbs_EDGE) {
225 TopoDS_Edge oldEdge = TopoDS::Edge(aShape);
226 TopoDS_Edge anewEdge;
227 TopoDS_Face F,newFace;
229 if(!anAncShape.IsNull()) {
230 F = TopoDS::Face(anAncShape);
232 if(myMapNewShapes.IsBound(F))
233 newFace = TopoDS::Face(myMapNewShapes.Find(F));
236 anewEdge = TopoDS::Edge(aNewShape);
237 aRebuild = RebuildShape(oldEdge,anewEdge,F,newFace,isBound);
238 aNewShape = anewEdge;
241 else if(shtype == TopAbs_VERTEX) {
243 TopoDS_Vertex aV = TopoDS::Vertex(aShape);
244 aRebuild = RebuildShape(aV,aVnew);
251 //Removing location from sub-shapes in dependance of LevelRemoving and re-building shape.
255 aNewShape = theShape.EmptyCopied();
256 TopLoc_Location oldLoc,nullloc;
257 oldLoc = theShape.Location();
258 if(!oldLoc.IsIdentity())
259 aNewShape.Location(nullloc);
260 TopAbs_Orientation orient = theShape.Orientation();
261 aNewShape.Orientation(TopAbs_FORWARD);
262 TopoDS_Iterator aIt(aShape,Standard_False,isRemoveLoc);
263 for( ; aIt.More(); aIt.Next()) {
264 TopoDS_Shape subshape = aIt.Value();
265 TopoDS_Shape anewsubshape;
266 Standard_Boolean isDoneSubShape = MakeNewShape(subshape,anAncShape,anewsubshape,isRemoveLoc);
267 isDone = (isDone || isDoneSubShape);
268 aB.Add(aNewShape,anewsubshape);
272 aNewShape.Orientation(orient);
273 else aNewShape = aShape;
274 myMapNewShapes.Bind(aShape,aNewShape);
275 if(!theRemoveLoc && !oldLoc.IsIdentity())
276 aNewShape.Location(oldLoc);
279 theNewShape = aNewShape;
282 return (isDone || isBound);