7b6ca49e9c89965682a27845616113f255cf9b67
[occt.git] / src / LocOpe / LocOpe_Prism.cxx
1 // Created on: 1996-09-04
2 // Created by: Olga PILLOT
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRepLib_MakeVertex.hxx>
19 #include <BRepSweep_Prism.hxx>
20 #include <BRepTools_Modifier.hxx>
21 #include <BRepTools_TrsfModification.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_Line.hxx>
24 #include <Geom_TrimmedCurve.hxx>
25 #include <gp_Ax1.hxx>
26 #include <gp_Trsf.hxx>
27 #include <gp_Vec.hxx>
28 #include <LocOpe.hxx>
29 #include <LocOpe_BuildShape.hxx>
30 #include <LocOpe_Prism.hxx>
31 #include <Standard_NoSuchObject.hxx>
32 #include <StdFail_NotDone.hxx>
33 #include <TColgp_SequenceOfPnt.hxx>
34 #include <TopExp.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopoDS.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Shape.hxx>
39 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
40
41 //=======================================================================
42 //function : LocOpe_Prism
43 //purpose  : 
44 //=======================================================================
45 LocOpe_Prism::LocOpe_Prism(): myDone(Standard_False)
46 {}
47
48 //=======================================================================
49 //function : LocOpe_Prism
50 //purpose  : 
51 //=======================================================================
52
53 LocOpe_Prism::LocOpe_Prism(const TopoDS_Shape&  Base,
54                            const gp_Vec& V):
55        myBase(Base), myVec(V), myIsTrans(Standard_False)
56
57 {
58   IntPerf();
59 }
60
61 //=======================================================================
62 //function : LocOpe_Prism
63 //purpose  : 
64 //=======================================================================
65
66 LocOpe_Prism::LocOpe_Prism(const TopoDS_Shape&  Base,
67                            const gp_Vec& V,
68                            const gp_Vec& Vtra):
69        myBase(Base), myVec(V), myTra(Vtra), myIsTrans(Standard_True)
70
71 {
72   IntPerf();
73
74 }
75
76 //=======================================================================
77 //function : Perform
78 //purpose  : 
79 //=======================================================================
80
81 void LocOpe_Prism::Perform(const TopoDS_Shape& Base,
82                            const gp_Vec& V)
83 {
84   myMap.Clear();
85   myFirstShape.Nullify();
86   myLastShape.Nullify();
87   myBase.Nullify();
88   myRes.Nullify();
89
90   myBase = Base;
91   myVec = V;
92   myIsTrans = Standard_False;
93   IntPerf();
94 }
95
96 //=======================================================================
97 //function : Perform
98 //purpose  : 
99 //=======================================================================
100
101 void LocOpe_Prism::Perform(const TopoDS_Shape& Base,
102                            const gp_Vec& V,
103                            const gp_Vec& Vtra)
104 {
105   myMap.Clear();
106   myFirstShape.Nullify();
107   myLastShape.Nullify();
108   myBase.Nullify();
109   myRes.Nullify();
110
111   myBase = Base;
112   myVec = V;
113   myTra = Vtra;
114   myIsTrans = Standard_True;
115   IntPerf();
116 }
117
118
119 //=======================================================================
120 //function : IntPerf
121 //purpose  : 
122 //=======================================================================
123
124 void LocOpe_Prism::IntPerf()
125 {
126   TopoDS_Shape theBase = myBase;
127   BRepTools_Modifier Modif;
128   if (myIsTrans) {
129     gp_Trsf T;
130     T.SetTranslation(myTra);
131     Handle(BRepTools_TrsfModification) modbase = 
132       new BRepTools_TrsfModification(T);
133     Modif.Init(theBase);
134     Modif.Perform(modbase);
135     theBase = Modif.ModifiedShape(theBase);
136   }
137   
138   BRepSweep_Prism thePrism(theBase,myVec);
139
140   myFirstShape = thePrism.FirstShape();
141   myLastShape = thePrism.LastShape();
142
143   TopExp_Explorer exp;
144   if (theBase.ShapeType() == TopAbs_FACE) {
145     for (exp.Init(theBase,TopAbs_EDGE);exp.More();exp.Next()) {
146       const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
147       if (!myMap.IsBound(edg)) {
148         TopTools_ListOfShape thelist;
149         myMap.Bind(edg, thelist);
150         TopoDS_Shape desc = thePrism.Shape(edg);
151         if (!desc.IsNull()) {
152           myMap(edg).Append(desc);
153         }
154       }
155     }
156     myRes = thePrism.Shape();
157   }
158
159   else {
160     // Cas base != FACE
161     TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
162     TopExp::MapShapesAndAncestors(theBase,TopAbs_EDGE,TopAbs_FACE,theEFMap);
163     TopTools_ListOfShape lfaces;
164     Standard_Boolean toremove = Standard_False;
165     for (Standard_Integer i=1; i<=theEFMap.Extent(); i++) {
166       const TopoDS_Shape& edg = theEFMap.FindKey(i);
167       TopTools_ListOfShape thelist1;
168       myMap.Bind(edg, thelist1);
169       TopoDS_Shape desc = thePrism.Shape(edg);
170       if (!desc.IsNull()) {
171         if (theEFMap(i).Extent() >= 2) {
172           toremove = Standard_True;
173         }
174         else {
175           myMap(edg).Append(desc);
176           lfaces.Append(desc);
177         }
178       }
179     }
180     if(toremove) {
181       // Rajouter les faces de FirstShape et LastShape
182       for (exp.Init(myFirstShape,TopAbs_FACE);exp.More();exp.Next()) {
183         lfaces.Append(exp.Current());
184       }
185       for (exp.Init(myLastShape,TopAbs_FACE);exp.More();exp.Next()) {
186         lfaces.Append(exp.Current());
187       }
188       
189       LocOpe_BuildShape BS(lfaces);
190       myRes = BS.Shape();
191     }
192     else {
193       for (exp.Init(theBase,TopAbs_EDGE);exp.More();exp.Next()) {
194         const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
195         if (!myMap.IsBound(edg)) {
196           TopTools_ListOfShape thelist2;
197           myMap.Bind(edg, thelist2);
198           TopoDS_Shape desc = thePrism.Shape(edg);
199           if (!desc.IsNull()) {
200             myMap(edg).Append(desc);
201           }
202         }
203       }
204       myRes = thePrism.Shape();
205     }
206   }
207
208   if (myIsTrans) {
209     // m-a-j des descendants
210     TopExp_Explorer anExp;
211     for (anExp.Init(myBase,TopAbs_EDGE); anExp.More(); anExp.Next()) {
212       const TopoDS_Edge& edg = TopoDS::Edge(anExp.Current());
213       const TopoDS_Edge& edgbis = TopoDS::Edge(Modif.ModifiedShape(edg));
214       if (!edgbis.IsSame(edg) && myMap.IsBound(edgbis)) {
215         myMap.Bind(edg,myMap(edgbis));
216         myMap.UnBind(edgbis);
217       }
218     }
219   }
220   myDone = Standard_True;
221 }
222
223 //=======================================================================
224 //function : Shape
225 //purpose  : 
226 //=======================================================================
227
228 const TopoDS_Shape& LocOpe_Prism::Shape () const
229 {
230   if (!myDone) {
231     throw StdFail_NotDone();
232   }
233   return myRes;
234 }
235
236
237 //=======================================================================
238 //function : FirstShape
239 //purpose  : 
240 //=======================================================================
241
242 const TopoDS_Shape& LocOpe_Prism::FirstShape () const
243 {
244   return myFirstShape;
245 }
246
247 //=======================================================================
248 //function : LastShape
249 //purpose  : 
250 //=======================================================================
251
252 const TopoDS_Shape& LocOpe_Prism::LastShape () const
253 {
254   return myLastShape;
255 }
256
257
258 //=======================================================================
259 //function : Shapes
260 //purpose  : 
261 //=======================================================================
262
263 const TopTools_ListOfShape& LocOpe_Prism::Shapes (const TopoDS_Shape& S) const
264 {
265   return myMap(S);
266 }
267
268
269 //=======================================================================
270 //function : Curves
271 //purpose  : 
272 //=======================================================================
273
274 void LocOpe_Prism::Curves(TColGeom_SequenceOfCurve& Scurves) const
275 {
276   Scurves.Clear();
277   TColgp_SequenceOfPnt spt;
278   LocOpe::SampleEdges(myFirstShape,spt);
279   Standard_Real height = 
280     Sqrt(myVec.X()*myVec.X()+myVec.Y()*myVec.Y()+myVec.Z()*myVec.Z());
281   Standard_Real u1 = -2*height;
282   Standard_Real u2 =  2*height;
283
284   for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
285     gp_Ax1 theAx(spt(jj),myVec);
286     Handle(Geom_Line) theLin = new Geom_Line(theAx);
287     Handle(Geom_TrimmedCurve) trlin = 
288       new Geom_TrimmedCurve(theLin, u1, u2, Standard_True);   
289     Scurves.Append(trlin);
290   }
291 }
292
293 //=======================================================================
294 //function : BarycCurve
295 //purpose  : 
296 //=======================================================================
297
298 Handle(Geom_Curve) LocOpe_Prism::BarycCurve() const
299 {
300   gp_Pnt bar(0., 0., 0.);
301   TColgp_SequenceOfPnt spt;
302   LocOpe::SampleEdges(myFirstShape,spt);
303   for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
304     const gp_Pnt& pvt = spt(jj);
305     bar.ChangeCoord() += pvt.XYZ();
306   }
307   bar.ChangeCoord().Divide(spt.Length());
308   gp_Ax1 newAx(bar,myVec);
309   Handle(Geom_Line) theLin = new Geom_Line(newAx);
310   return theLin;
311 }
312