]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_PrismDriver.cxx
Salome HOME
IMPs 21044, 21057, 21067
[modules/geom.git] / src / GEOMImpl / GEOMImpl_PrismDriver.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 #include <GEOMImpl_PrismDriver.hxx>
23
24 #include <GEOMImpl_IPrism.hxx>
25 #include <GEOMImpl_IShapesOperations.hxx>
26 #include <GEOMImpl_IMeasureOperations.hxx>
27 #include <GEOMImpl_PipeDriver.hxx>
28 #include <GEOMImpl_Types.hxx>
29 #include <GEOM_Function.hxx>
30
31 #include <BRepPrimAPI_MakePrism.hxx>
32 #include <BRepBuilderAPI_MakeEdge.hxx>
33 #include <BRepBuilderAPI_MakeWire.hxx>
34 #include <BRepBuilderAPI_MakeVertex.hxx>
35 #include <BRepBuilderAPI_Transform.hxx>
36 #include <BRep_Tool.hxx>
37
38 #include <TopAbs.hxx>
39 #include <TopExp.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopTools_HSequenceOfShape.hxx>
45 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
46
47 #include <Precision.hxx>
48 #include <gp_Ax3.hxx>
49 #include <gp_Pnt.hxx>
50 #include <gp_Vec.hxx>
51 #include <gp_Trsf.hxx>
52
53 #include <Standard_Stream.hxx>
54
55 #include <Standard_ConstructionError.hxx>
56
57 //=======================================================================
58 //function : GetID
59 //purpose  :
60 //=======================================================================
61 const Standard_GUID& GEOMImpl_PrismDriver::GetID()
62 {
63   static Standard_GUID aPrismDriver("FF1BBB17-5D14-4df2-980B-3A668264EA16");
64   return aPrismDriver;
65 }
66
67
68 //=======================================================================
69 //function : GEOMImpl_PrismDriver
70 //purpose  :
71 //=======================================================================
72 GEOMImpl_PrismDriver::GEOMImpl_PrismDriver()
73 {
74 }
75
76 //=======================================================================
77 //function : Execute
78 //purpose  :
79 //=======================================================================
80 Standard_Integer GEOMImpl_PrismDriver::Execute(TFunction_Logbook& log) const
81 {
82   if (Label().IsNull()) return 0;
83   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
84
85   GEOMImpl_IPrism aCI (aFunction);
86   Standard_Integer aType = aFunction->GetType();
87
88   TopoDS_Shape aShape;
89
90   if (aType == PRISM_BASE_VEC_H || aType == PRISM_BASE_VEC_H_2WAYS) {
91     Handle(GEOM_Function) aRefBase = aCI.GetBase();
92     Handle(GEOM_Function) aRefVector = aCI.GetVector();
93     TopoDS_Shape aShapeBase = aRefBase->GetValue();
94     TopoDS_Shape aShapeVec = aRefVector->GetValue();
95     if (aShapeVec.ShapeType() == TopAbs_EDGE) {
96       TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
97       TopoDS_Vertex V1, V2;
98       TopExp::Vertices(anE, V1, V2, Standard_True);
99       if (!V1.IsNull() && !V2.IsNull()) {
100         gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
101         if (Abs(aCI.GetH()) < Precision::Confusion()) {
102           Standard_ConstructionError::Raise("Absolute value of prism height is too small");
103         }
104         if (aV.Magnitude() > Precision::Confusion()) {
105           aV.Normalize();
106           if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
107             aShape = MakeScaledPrism(aShapeBase, aV * aCI.GetH(), aCI.GetScale());
108           }
109           else {
110             if (aType == PRISM_BASE_VEC_H_2WAYS) {
111               gp_Trsf aTrsf;
112               aTrsf.SetTranslation((-aV) * aCI.GetH());
113               BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
114               aShapeBase = aTransformation.Shape();
115               aCI.SetH(aCI.GetH()*2);
116             }
117             aShape = BRepPrimAPI_MakePrism(aShapeBase, aV * aCI.GetH(), Standard_False).Shape();
118           }
119         }
120       }
121     }
122   } else if (aType == PRISM_BASE_TWO_PNT || aType == PRISM_BASE_TWO_PNT_2WAYS) {
123     Handle(GEOM_Function) aRefBase = aCI.GetBase();
124     Handle(GEOM_Function) aRefPnt1 = aCI.GetFirstPoint();
125     Handle(GEOM_Function) aRefPnt2 = aCI.GetLastPoint();
126     TopoDS_Shape aShapeBase = aRefBase->GetValue();
127     TopoDS_Shape aShapePnt1 = aRefPnt1->GetValue();
128     TopoDS_Shape aShapePnt2 = aRefPnt2->GetValue();
129     if (aShapePnt1.ShapeType() == TopAbs_VERTEX &&
130         aShapePnt2.ShapeType() == TopAbs_VERTEX) {
131       TopoDS_Vertex V1 = TopoDS::Vertex(aShapePnt1);
132       TopoDS_Vertex V2 = TopoDS::Vertex(aShapePnt2);
133       if (!V1.IsNull() && !V2.IsNull()) {
134         gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
135         if (aV.Magnitude() > gp::Resolution()) {
136           if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
137             aShape = MakeScaledPrism(aShapeBase, aV, aCI.GetScale());
138           }
139           else {
140             if (aType == PRISM_BASE_TWO_PNT_2WAYS) {
141               gp_Trsf aTrsf;
142               aTrsf.SetTranslation(-aV);
143               BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
144               aShapeBase = aTransformation.Shape();
145               aV = aV * 2;
146             }
147             aShape = BRepPrimAPI_MakePrism(aShapeBase, aV, Standard_False).Shape();
148           }
149         }
150       }
151     }
152   } else if (aType == PRISM_BASE_DXDYDZ || aType == PRISM_BASE_DXDYDZ_2WAYS) {
153     Handle(GEOM_Function) aRefBase = aCI.GetBase();
154     TopoDS_Shape aShapeBase = aRefBase->GetValue();
155     gp_Vec aV (aCI.GetDX(), aCI.GetDY(), aCI.GetDZ());
156     if (aV.Magnitude() > gp::Resolution()) {
157       if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
158         aShape = MakeScaledPrism(aShapeBase, aV, aCI.GetScale());
159       }
160       else {
161         if (aType == PRISM_BASE_DXDYDZ_2WAYS) {
162           gp_Trsf aTrsf;
163           aTrsf.SetTranslation(-aV);
164           BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
165           aShapeBase = aTransformation.Shape();
166           aV = aV * 2;
167         }
168         aShape = BRepPrimAPI_MakePrism(aShapeBase, aV, Standard_False).Shape();
169       }
170     }
171   }
172
173   if (aShape.IsNull()) return 0;
174
175   TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape);
176   aFunction->SetValue(aRes);
177
178   log.SetTouched(Label());
179
180   return 1;
181 }
182
183 //=======================================================================
184 //function : MakeScaledPrism
185 //purpose  :
186 //=======================================================================
187 TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShapeBase,
188                                                     const gp_Vec&       theVector,
189                                                     const Standard_Real theScaleFactor)
190 {
191   TopoDS_Shape aShape;
192
193   // 1. aCDG = geompy.MakeCDG(theBase)
194   gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(theShapeBase);
195   gp_Pnt aCDG = aPos.Location();
196   TopoDS_Shape aShapeCDG_1 = BRepBuilderAPI_MakeVertex(aCDG).Shape();
197
198   // 2. Scale = geompy.MakeScaleTransform(theBase, aCDG, theScaleFactor)
199
200   // Bug 6839: Check for standalone (not included in faces) degenerated edges
201   TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
202   TopExp::MapShapesAndAncestors(theShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
203   Standard_Integer i, nbE = aEFMap.Extent();
204   for (i = 1; i <= nbE; i++) {
205     TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
206     if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
207       const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
208       if (aFaces.IsEmpty())
209         Standard_ConstructionError::Raise
210           ("Scaling aborted : cannot scale standalone degenerated edge");
211     }
212   }
213
214   // Perform Scaling
215   gp_Trsf aTrsf;
216   aTrsf.SetScale(aCDG, theScaleFactor);
217   BRepBuilderAPI_Transform aBRepTrsf (theShapeBase, aTrsf, Standard_False);
218   TopoDS_Shape aScale = aBRepTrsf.Shape();
219
220   // 3. aBase2 = geompy.MakeTranslationVectorDistance(Scale, theVec, theH)
221   gp_Trsf aTrsf3;
222   aTrsf3.SetTranslation(theVector);
223   TopLoc_Location aLocOrig = aScale.Location();
224   gp_Trsf aTrsfOrig = aLocOrig.Transformation();
225   TopLoc_Location aLocRes (aTrsf3 * aTrsfOrig);
226   TopoDS_Shape aBase2 = aScale.Located(aLocRes);
227
228   // 4. aCDG_2 = geompy.MakeTranslationVectorDistance(aCDG, theVec, theH)
229   gp_Pnt aCDG_2 = aCDG.Translated(theVector);
230   TopoDS_Shape aShapeCDG_2 = BRepBuilderAPI_MakeVertex(aCDG_2).Shape();
231
232   // 5. Vector = geompy.MakeVector(aCDG, aCDG_2)
233   TopoDS_Shape aShapeVec = BRepBuilderAPI_MakeEdge(aCDG, aCDG_2).Shape();
234   TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
235   TopoDS_Wire aWirePath = BRepBuilderAPI_MakeWire(anEdge);
236
237   // 6. aPrism = geompy.MakePipeWithDifferentSections([theBase, aBase2], [aCDG, aCDG_2], Vector, False, False)
238   Handle(TopTools_HSequenceOfShape) aBases = new TopTools_HSequenceOfShape;
239   aBases->Append(theShapeBase);
240   aBases->Append(aBase2);
241
242   Handle(TopTools_HSequenceOfShape) aLocs = new TopTools_HSequenceOfShape;
243   aLocs->Append(aShapeCDG_1);
244   aLocs->Append(aShapeCDG_2);
245
246   aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections(aWirePath, aBases, aLocs, false, false);
247   return aShape;
248 }
249
250 //=======================================================================
251 //function : GEOMImpl_PrismDriver_Type_
252 //purpose  :
253 //=======================================================================
254 Standard_EXPORT Handle_Standard_Type& GEOMImpl_PrismDriver_Type_()
255 {
256
257   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
258   if (aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
259   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
260   if (aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
261   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
262   if (aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
263
264   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
265   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PrismDriver",
266                                                          sizeof(GEOMImpl_PrismDriver),
267                                                          1,
268                                                          (Standard_Address)_Ancestors,
269                                                          (Standard_Address)NULL);
270
271   return _aType;
272 }
273
274 //=======================================================================
275 //function : DownCast
276 //purpose  :
277 //=======================================================================
278 const Handle(GEOMImpl_PrismDriver) Handle(GEOMImpl_PrismDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
279 {
280   Handle(GEOMImpl_PrismDriver) _anOtherObject;
281
282   if (!AnObject.IsNull()) {
283      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PrismDriver))) {
284        _anOtherObject = Handle(GEOMImpl_PrismDriver)((Handle(GEOMImpl_PrismDriver)&)AnObject);
285      }
286   }
287
288   return _anOtherObject;
289 }