0024530: TKMesh - remove unused package IntPoly
[occt.git] / src / BRepProj / BRepProj_Projection.cxx
CommitLineData
b311480e 1// Copyright (c) 1998-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
973c2be1 6// This library is free software; you can redistribute it and / or modify it
7// under the terms of the GNU Lesser General Public version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15#include <BRepProj_Projection.ixx>
16
17#include <BRepAlgo_Section.hxx>
18
19#include <Precision.hxx>
20#include <BRepBndLib.hxx>
21#include <BRepTools_TrsfModification.hxx>
22#include <BRepTools_Modifier.hxx>
23#include <BRepLib_MakeEdge.hxx>
24#include <BRepLib_MakeWire.hxx>
25#include <BRep_Tool.hxx>
26#include <Bnd_Box.hxx>
27
28#include <BRepSweep_Prism.hxx>
29#include <BRepFill_Generator.hxx>
30#include <TopExp.hxx>
31#include <TopExp_Explorer.hxx>
32#include <TopLoc_Location.hxx>
33#include <gp_Dir.hxx>
34#include <gp_Pnt.hxx>
35#include <gp_Vec.hxx>
36#include <gp_Trsf.hxx>
37#include <TopoDS.hxx>
38#include <TopoDS_Iterator.hxx>
39#include <TopoDS_Shape.hxx>
40#include <TopTools_ListOfShape.hxx>
41#include <TopTools_ListIteratorOfListOfShape.hxx>
42#include <BRep_Builder.hxx>
43#include <ShapeAnalysis_FreeBounds.hxx>
44
45#include <Standard_NullObject.hxx>
46#include <Standard_ConstructionError.hxx>
47
48//=======================================================================
49//function : DistanceOut
50//purpose : Compute the minimum distance between input shapes
51// (using Bounding Boxes of each Shape)
52//=======================================================================
53
54static Standard_Real DistanceOut (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
55{
56 Bnd_Box BBox1, BBox2;
57 BRepBndLib::Add(S1,BBox1);
58 BRepBndLib::Add(S2,BBox2);
59 return BBox1.Distance(BBox2);
60}
61
62//=======================================================================
63//function : DistanceIn
64//purpose : Compute the maximum distance between input Shapes
65// we compute the maximum dimension of each Bounding Box and then
66// add each other with the minimum distance of shapes.
67//=======================================================================
68
69static Standard_Real DistanceIn (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
70{
71 Bnd_Box LBBox,SBBox;
72 BRepBndLib::Add(S1,SBBox);
73 BRepBndLib::Add(S2,LBBox);
74
75 Standard_Real LXmin, LYmin, LZmin, LXmax, LYmax, LZmax,
76 SXmin, SYmin, SZmin, SXmax, SYmax, SZmax;
77 SBBox.Get(SXmin, SYmin, SZmin,
78 SXmax, SYmax, SZmax);
79 LBBox.Get(LXmin, LYmin, LZmin,
80 LXmax, LYmax, LZmax);
81
82 //Compute the max distance between input shapes------------//
83 gp_XYZ Lmin(LXmin, LYmin, LZmin),
84 Lmax(LXmax, LYmax, LZmax);
85 gp_XYZ Smin(SXmin, SYmin, SZmin),
86 Smax(SXmax, SYmax, SZmax);
87 Lmax.Subtract(Lmin);
88 Smax.Subtract(Smin);
89 return Lmax.Modulus() + Smax.Modulus() + DistanceOut(S1, S2);
90}
91
92//=======================================================================
93//function : BuildSection
94//purpose : Cuts theShape by theTool using BRepAlgoAPI_Section and
95// stores result as set of connected wires and compound
96//=======================================================================
97
98void BRepProj_Projection::BuildSection (const TopoDS_Shape& theShape,
99 const TopoDS_Shape& theTool)
100{
101 myIsDone = Standard_False;
102 mySection.Nullify();
103 myShape.Nullify();
104 myItr = 0;
105
106 // if theShape is compound, extract only faces -- section algorithm
107 // may refuse to work if e.g. vertex is present
108 TopoDS_Shape aShape;
109 if (theShape.ShapeType() == TopAbs_FACE ||
110 theShape.ShapeType() == TopAbs_SHELL ||
111 theShape.ShapeType() == TopAbs_SOLID ||
112 theShape.ShapeType() == TopAbs_COMPSOLID)
113 aShape = theShape;
114 else if (theShape.ShapeType() == TopAbs_COMPOUND)
115 {
116 TopoDS_Compound C;
117 BRep_Builder B;
118 TopExp_Explorer exp (theShape, TopAbs_FACE);
119 for (; exp.More(); exp.Next())
120 {
121 if ( C.IsNull() )
122 B.MakeCompound (C);
123 B.Add (C, exp.Current());
124 }
125 aShape = C;
126 }
127 if ( aShape.IsNull() )
128 Standard_ConstructionError::Raise(__FILE__": target shape has no faces");
129
130 // build section computing pcurves on the shape
131// BRepAlgoAPI_Section aSectionTool (aShape, theTool, Standard_False);
132 BRepAlgo_Section aSectionTool (aShape, theTool, Standard_False);
133 aSectionTool.Approximation (Standard_True);
134 aSectionTool.ComputePCurveOn1 (Standard_True);
135 aSectionTool.Build();
136
137 // check for successful work of the section tool
138 if (! aSectionTool.IsDone())
139 return;
140
141 // get edges of the result
142 Handle(TopTools_HSequenceOfShape) anEdges = new TopTools_HSequenceOfShape;
143 TopExp_Explorer exp(aSectionTool.Shape(), TopAbs_EDGE);
144 for (; exp.More(); exp.Next())
145 anEdges->Append (exp.Current());
146
147 // if no edges are found, this means that this section yields no result
148 if (anEdges->Length() <= 0)
149 return;
150
151 // connect edges to wires using ShapeAnalysis functionality
152 ShapeAnalysis_FreeBounds::ConnectEdgesToWires (anEdges, Precision::Confusion(),
153 Standard_True, mySection);
154 myIsDone = (! mySection.IsNull() && mySection->Length() > 0);
155
156 // collect all resulting wires to compound
157 if ( myIsDone )
158 {
159 BRep_Builder B;
160 B.MakeCompound (myShape);
161 for (Standard_Integer i=1; i <= mySection->Length(); i++)
162 B.Add (myShape, mySection->Value(i));
163
164 // initialize iteration (for compatibility with previous versions)
165 myItr = 1;
166 }
167}
168
169//=======================================================================
170//function : BRepProj_Projection
171//purpose : Cylindrical Projection
172//=======================================================================
173
174BRepProj_Projection::BRepProj_Projection(const TopoDS_Shape& Wire,
175 const TopoDS_Shape& Shape,
176 const gp_Dir& D)
177: myIsDone(Standard_False), myItr(0)
178{
179 // Check the input
180 Standard_NullObject_Raise_if((Wire.IsNull() || Shape.IsNull()),__FILE__": null input shape");
181 if (Wire.ShapeType() != TopAbs_EDGE &&
182 Wire.ShapeType() != TopAbs_WIRE )
183 Standard_ConstructionError::Raise(__FILE__": projected shape is neither wire nor edge");
184
185 // compute the "length" of the cylindrical surface to build
186 Standard_Real mdis = DistanceIn(Wire, Shape);
187 gp_Vec Vsup (D.XYZ() * 2 * mdis);
188 gp_Vec Vinf (D.XYZ() * -mdis);
189
190 // move the base of the cylindrical surface by translating it by -mdis
191 gp_Trsf T;
192 T.SetTranslation(Vinf);
193 // Note: it is necessary to create copy of wire to avoid adding new pcurves into it
194 Handle(BRepTools_TrsfModification) Trsf = new BRepTools_TrsfModification(T);
195 BRepTools_Modifier Modif (Wire, Trsf);
196 TopoDS_Shape WireBase = Modif.ModifiedShape(Wire);
197
198 // Creation of a cylindrical surface
199 BRepSweep_Prism CylSurf (WireBase, Vsup, Standard_False);
200
201 // Perform section
202 BuildSection (Shape, CylSurf.Shape());
203}
204
205//=======================================================================
206//function : BRepProj_Projection
207//purpose : Conical projection
208//=======================================================================
209
210BRepProj_Projection::BRepProj_Projection (const TopoDS_Shape& Wire,
211 const TopoDS_Shape& Shape,
212 const gp_Pnt& P)
213: myIsDone(Standard_False), myItr(0)
214{
215 // Check the input
216 Standard_NullObject_Raise_if((Wire.IsNull() || Shape.IsNull()),__FILE__": null input shape");
217 if (Wire.ShapeType() != TopAbs_EDGE &&
218 Wire.ShapeType() != TopAbs_WIRE )
219 Standard_ConstructionError::Raise(__FILE__": projected shape is neither wire nor edge");
220
221 // if Wire is only an edge, transform it into a Wire
222 TopoDS_Wire aWire;
223 if (Wire.ShapeType() == TopAbs_EDGE)
224 {
225 BRep_Builder BB;
226 BB.MakeWire(aWire);
227 BB.Add(aWire, Wire);
228 }
229 else
230 aWire = TopoDS::Wire(Wire);
231
232 // compute the "length" of the conical surface to build
233 Standard_Real mdis = DistanceIn(Wire, Shape);
234
235 // Initialize iterator to get first sub-shape of Wire
236 TopExp_Explorer ExpWire;
237 ExpWire.Init (aWire, TopAbs_VERTEX);
238
239 // get the first Point of the first sub-shape os the Wire
240 gp_Pnt PC = BRep_Tool::Pnt(TopoDS::Vertex(ExpWire.Current()));
241
242 // compute the ratio of the scale transformation
243 Standard_Real Scale = PC.Distance(P);
244 if ( Abs (Scale) < Precision::Confusion() )
245 Standard_ConstructionError::Raise("Projection");
246 Scale = 1. + mdis / Scale;
247
248 // move the base of the conical surface by scaling it with ratio Scale
249 // then we do a symmetric relative to a point. So we have two generators
250 // for building a "semi-infinite" conic surface
251 gp_Trsf T;
252 T.SetScale(P, Scale);
253 Handle(BRepTools_TrsfModification) Tsca = new BRepTools_TrsfModification(T);
254 BRepTools_Modifier ModifScale(aWire,Tsca);
255 TopoDS_Shape ShapeGen1 = ModifScale.ModifiedShape(aWire);
256
257 T.SetMirror(P);
258 Handle(BRepTools_TrsfModification) Tmir = new BRepTools_TrsfModification(T);
259 BRepTools_Modifier ModifMirror(ShapeGen1,Tmir);
260 TopoDS_Shape ShapeGen2 = ModifMirror.ModifiedShape(ShapeGen1);
261
262 // Build the Ruled surface based shape
263 BRepFill_Generator RuledSurf;
264 RuledSurf.AddWire(TopoDS::Wire(ShapeGen1));
265 RuledSurf.AddWire(TopoDS::Wire(ShapeGen2));
266 RuledSurf.Perform();
267 TopoDS_Shell SurfShell = RuledSurf.Shell();
268
269 // Perform section
270 BuildSection (Shape, SurfShell);
271}