973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
42cf5bc1 |
14 | |
7fd59977 |
15 | #include <BRep_Builder.hxx> |
42cf5bc1 |
16 | #include <BRep_CurveRepresentation.hxx> |
17 | #include <BRep_GCurve.hxx> |
18 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
19 | #include <BRep_TEdge.hxx> |
7fd59977 |
20 | #include <BRep_Tool.hxx> |
7fd59977 |
21 | #include <Geom2d_Curve.hxx> |
42cf5bc1 |
22 | #include <Geom_Curve.hxx> |
7fd59977 |
23 | #include <Geom_Geometry.hxx> |
42cf5bc1 |
24 | #include <Geom_Plane.hxx> |
25 | #include <Geom_Surface.hxx> |
26 | #include <gp_Pnt.hxx> |
7fd59977 |
27 | #include <gp_Trsf.hxx> |
42cf5bc1 |
28 | #include <ShapeBuild_Edge.hxx> |
29 | #include <ShapeUpgrade_RemoveLocations.hxx> |
30 | #include <Standard_Type.hxx> |
7fd59977 |
31 | #include <TColStd_ListIteratorOfListOfTransient.hxx> |
7fd59977 |
32 | #include <TColStd_ListOfTransient.hxx> |
42cf5bc1 |
33 | #include <TopAbs_ShapeEnum.hxx> |
34 | #include <TopExp.hxx> |
35 | #include <TopExp_Explorer.hxx> |
36 | #include <TopLoc_Location.hxx> |
37 | #include <TopoDS.hxx> |
38 | #include <TopoDS_Edge.hxx> |
39 | #include <TopoDS_Face.hxx> |
40 | #include <TopoDS_Iterator.hxx> |
41 | #include <TopoDS_Shape.hxx> |
42 | #include <TopoDS_Vertex.hxx> |
43 | #include <TopTools_DataMapOfShapeShape.hxx> |
b311480e |
44 | |
42cf5bc1 |
45 | //#include <ShapeUpgrade_DataMapOfShapeListOfTransient.hxx> |
7fd59977 |
46 | //======================================================================= |
47 | //function : ShapeUpgrade_RemoveLocations |
48 | //purpose : |
49 | //======================================================================= |
7fd59977 |
50 | ShapeUpgrade_RemoveLocations::ShapeUpgrade_RemoveLocations() |
51 | { |
52 | myLevelRemoving = TopAbs_SHAPE; |
53 | } |
54 | |
55 | //======================================================================= |
56 | //function : Remove |
57 | //purpose : |
58 | //======================================================================= |
59 | |
60 | Standard_Boolean ShapeUpgrade_RemoveLocations::Remove(const TopoDS_Shape& theShape) |
61 | { |
62 | TopoDS_Shape aShape = theShape; |
63 | myShape = aShape; |
64 | TopAbs_ShapeEnum shtype = theShape.ShapeType(); |
65 | Standard_Boolean isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) || |
66 | ((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype))); |
67 | TopoDS_Shape S; |
68 | Standard_Boolean isDone = MakeNewShape(theShape,S,myShape,isRemoveLoc); |
69 | |
70 | return isDone; |
71 | |
72 | } |
73 | |
74 | //======================================================================= |
75 | //function : RebuildShape |
76 | //purpose : |
77 | //======================================================================= |
78 | static Standard_Boolean RebuildShape(const TopoDS_Face& theFace, TopoDS_Face& theNewFace) |
79 | { |
80 | BRep_Builder aB; |
81 | TopLoc_Location aLoc; |
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; |
88 | } |
89 | return isRebuild; |
90 | } |
91 | //======================================================================= |
92 | //function : RebuildShape |
93 | //purpose : |
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) |
98 | { |
99 | Standard_Boolean isRebuild = Standard_False; |
100 | BRep_Builder aB; |
101 | if(!isBound) { |
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); |
107 | if(!C3d.IsNull()) { |
108 | if(!aLoc.IsIdentity()) { |
109 | Handle(Geom_Curve) anewC3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(aLoc.Transformation())); |
110 | C3d = anewC3d; |
111 | } |
112 | |
113 | aB.UpdateEdge(theNewEdge,C3d,BRep_Tool::Tolerance(theEdge)); |
114 | aB.Range(theNewEdge,First3d,Last3d); |
115 | } |
116 | theNewEdge.Orientation(theEdge.Orientation()); |
117 | if(BRep_Tool::Degenerated(theEdge)) |
118 | aB.Degenerated(theNewEdge,Standard_True); |
119 | isRebuild = Standard_True; |
120 | } |
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; |
126 | |
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(); |
133 | |
982a90fc |
134 | if(theFace.Orientation() == TopAbs_REVERSED) |
7fd59977 |
135 | OrEdge = ( OrEdge == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD); |
136 | |
137 | if(OrEdge == TopAbs_FORWARD) |
138 | aB.UpdateEdge(theNewEdge,c2d, c2d1,theNewFace,0); |
139 | else aB.UpdateEdge(theNewEdge,c2d1, c2d,theNewFace,0); |
140 | |
141 | } |
142 | } |
143 | else |
144 | aB.UpdateEdge(theNewEdge,c2d,theNewFace,0); |
145 | |
146 | if(!c2d.IsNull() || !c2d1.IsNull()) |
147 | aB.Range(theNewEdge,theNewFace,First2d,Last2d); |
148 | } |
149 | } |
150 | return isRebuild; |
151 | } |
152 | //======================================================================= |
153 | //function : RebuildShape |
154 | //purpose : |
155 | //======================================================================= |
156 | static Standard_Boolean RebuildShape(const TopoDS_Vertex& theVertex, TopoDS_Vertex& theNewVertex) |
157 | { |
158 | BRep_Builder aB; |
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; |
164 | } |
165 | //======================================================================= |
166 | //function : MakeNewShape |
167 | //purpose : |
168 | //======================================================================= |
169 | |
170 | Standard_Boolean ShapeUpgrade_RemoveLocations::MakeNewShape(const TopoDS_Shape& theShape, |
171 | const TopoDS_Shape& theAncShape, |
172 | TopoDS_Shape& theNewShape, |
173 | const Standard_Boolean theRemoveLoc) |
174 | { |
175 | Standard_Boolean isDone = Standard_False; |
176 | TopoDS_Shape aNewShape; |
177 | TopAbs_ShapeEnum shtype = theShape.ShapeType(); |
178 | BRep_Builder aB; |
179 | TopoDS_Shape aShape = theShape; |
180 | if(!theRemoveLoc && !theShape.Location().IsIdentity()) { |
181 | TopLoc_Location nulLoc; |
182 | aShape.Location(nulLoc); |
183 | } |
184 | Standard_Boolean isBound = myMapNewShapes.IsBound(aShape); |
185 | if(isBound) { |
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); |
191 | } |
192 | if(shtype != TopAbs_EDGE) { |
7fd59977 |
193 | theNewShape = aNewShape; |
ab860031 |
194 | return Standard_True; |
195 | } |
7fd59977 |
196 | } |
197 | |
198 | |
199 | Standard_Boolean isRemoveLoc = theRemoveLoc; |
200 | if(!theRemoveLoc) { |
201 | isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) || |
202 | ((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype))); |
203 | } |
204 | |
205 | Standard_Boolean aRebuild = Standard_False; |
206 | TopoDS_Shape anAncShape = theAncShape; |
207 | if(shtype == TopAbs_FACE) |
208 | anAncShape = aShape; |
209 | if(isRemoveLoc && (!aShape.Location().IsIdentity() || shtype == TopAbs_EDGE || shtype == TopAbs_FACE )) { |
210 | |
211 | //Rebuild geometry for shape with location. |
212 | if(shtype == TopAbs_FACE) { |
213 | TopoDS_Face anewFace; |
214 | TopoDS_Face oldFace = TopoDS::Face(aShape); |
215 | aRebuild = RebuildShape(oldFace,anewFace); |
216 | if(aRebuild) { |
217 | aNewShape = anewFace; |
218 | myMapNewShapes.Bind(oldFace,aNewShape); |
219 | } |
220 | |
221 | } |
222 | else if(shtype == TopAbs_EDGE) { |
223 | TopoDS_Edge oldEdge = TopoDS::Edge(aShape); |
224 | TopoDS_Edge anewEdge; |
225 | TopoDS_Face F,newFace; |
226 | |
227 | if(!anAncShape.IsNull()) { |
228 | F = TopoDS::Face(anAncShape); |
229 | newFace = F; |
230 | if(myMapNewShapes.IsBound(F)) |
231 | newFace = TopoDS::Face(myMapNewShapes.Find(F)); |
232 | } |
233 | if(isBound) |
234 | anewEdge = TopoDS::Edge(aNewShape); |
235 | aRebuild = RebuildShape(oldEdge,anewEdge,F,newFace,isBound); |
236 | aNewShape = anewEdge; |
237 | |
238 | } |
239 | else if(shtype == TopAbs_VERTEX) { |
240 | TopoDS_Vertex aVnew; |
241 | TopoDS_Vertex aV = TopoDS::Vertex(aShape); |
242 | aRebuild = RebuildShape(aV,aVnew); |
243 | if(aRebuild) |
244 | aNewShape = aVnew; |
245 | } |
246 | } |
247 | isDone = aRebuild; |
248 | |
249 | //Removing location from sub-shapes in dependance of LevelRemoving and re-building shape. |
250 | |
251 | if(!isBound) { |
ab860031 |
252 | if(!aRebuild) |
253 | { |
254 | aNewShape = theShape.EmptyCopied(); |
255 | // it is safe to simply copy Closed flag since this operation does not change topology |
256 | aNewShape.Closed (theShape.Closed()); |
257 | } |
7fd59977 |
258 | TopLoc_Location oldLoc,nullloc; |
259 | oldLoc = theShape.Location(); |
260 | if(!oldLoc.IsIdentity()) |
261 | aNewShape.Location(nullloc); |
262 | TopAbs_Orientation orient = theShape.Orientation(); |
263 | aNewShape.Orientation(TopAbs_FORWARD); |
264 | TopoDS_Iterator aIt(aShape,Standard_False,isRemoveLoc); |
265 | for( ; aIt.More(); aIt.Next()) { |
266 | TopoDS_Shape subshape = aIt.Value(); |
267 | TopoDS_Shape anewsubshape; |
268 | Standard_Boolean isDoneSubShape = MakeNewShape(subshape,anAncShape,anewsubshape,isRemoveLoc); |
269 | isDone = (isDone || isDoneSubShape); |
270 | aB.Add(aNewShape,anewsubshape); |
7fd59977 |
271 | } |
272 | if(isDone) |
273 | aNewShape.Orientation(orient); |
ab860031 |
274 | else |
275 | aNewShape = aShape; |
7fd59977 |
276 | myMapNewShapes.Bind(aShape,aNewShape); |
277 | if(!theRemoveLoc && !oldLoc.IsIdentity()) |
278 | aNewShape.Location(oldLoc); |
279 | |
280 | } |
281 | theNewShape = aNewShape; |
ab860031 |
282 | |
7fd59977 |
283 | return (isDone || isBound); |
284 | } |
285 | |