0024947: Redesign OCCT legacy type system -- automatic
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_RemoveLocations.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <ShapeUpgrade_RemoveLocations.ixx>
15 #include <TopAbs_ShapeEnum.hxx>
16 #include <TopLoc_Location.hxx>
17 #include <TopoDS_Face.hxx>
18 #include <TopoDS.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>
24 #include <TopExp.hxx>
25 #include <Geom_Curve.hxx>
26 #include <BRep_Tool.hxx>
27 #include <gp_Pnt.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>
33
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>
44
45 //=======================================================================
46 //function : ShapeUpgrade_RemoveLocations
47 //purpose  : 
48 //=======================================================================
49
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           
134           if(theFace.Orientation() == TopAbs_REVERSED)
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) {
193        theNewShape = aNewShape;
194        return Standard_True;
195      }
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) {
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     }
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);
271     }
272     if(isDone) 
273       aNewShape.Orientation(orient);
274     else
275       aNewShape = aShape;
276     myMapNewShapes.Bind(aShape,aNewShape);
277     if(!theRemoveLoc && !oldLoc.IsIdentity())
278       aNewShape.Location(oldLoc);
279     
280   }
281   theNewShape = aNewShape;
282
283   return (isDone || isBound);
284 }
285