0027350: Support for Universal Windows Platform
[occt.git] / src / BRepPrimAPI / BRepPrimAPI_MakeHalfSpace.cxx
1 // Created on: 1995-03-08
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1995-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 <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepBuilderAPI_MakeVertex.hxx>
21 #include <BRepExtrema_ExtPF.hxx>
22 #include <BRepLProp_SLProps.hxx>
23 #include <BRepPrimAPI_MakeHalfSpace.hxx>
24 #include <gp.hxx>
25 #include <gp_Dir.hxx>
26 #include <gp_Pnt.hxx>
27 #include <StdFail_NotDone.hxx>
28 #include <TopExp_Explorer.hxx>
29 #include <TopoDS.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <TopoDS_Shell.hxx>
32 #include <TopoDS_Solid.hxx>
33 #include <TopoDS_Vertex.hxx>
34
35 //=======================================================================
36 //function : FindExtrema
37 //purpose  : This finction is called to find the nearest normal projection
38 //           of a point <aPnt> on a face <aFace>.
39 //           1) return true if extrema are found.
40 //           2) Set in:
41 //             - Dist : The lower distance found.
42 //             - anOppositePnt : The corresponding point lying on the face
43 //             - U,V : The parameters of <anOppositePnt> on the face <aFace>
44 //=======================================================================
45 static Standard_Real FindExtrema(const gp_Pnt&        aPnt,
46                                  const TopoDS_Face&   aFace,
47                                        Standard_Real& Dist,
48                                        gp_Pnt&        anOppositePnt,
49                                        Standard_Real& U,
50                                        Standard_Real& V)
51 {
52   Standard_Integer intvalue=0;
53   Dist = RealLast();
54   TopoDS_Vertex RefVertex = BRepBuilderAPI_MakeVertex(aPnt);
55   
56   BRepExtrema_ExtPF ext(RefVertex,aFace);
57   
58   if (ext.IsDone() && ext.NbExt() > 0) {
59     // the point projection exist
60     Standard_Integer nbext = ext.NbExt();
61     for (Standard_Integer iext = 1; iext <= nbext; iext++) {
62       if (ext.SquareDistance(iext) < Dist) {
63         Dist     = ext.SquareDistance(iext);
64         intvalue = iext;
65       }
66     }
67     Dist = sqrt(Dist);
68   } else {
69     // compute the min distance with the face vertices
70     TopExp_Explorer explo(aFace, TopAbs_VERTEX);
71     for(; explo.More(); explo.Next()) {
72       const TopoDS_Vertex& vertex = TopoDS::Vertex(explo.Current());
73       gp_Pnt2d             param  = BRep_Tool::Parameters(vertex, aFace);
74       gp_Pnt               Pnt    = BRep_Tool::Pnt(vertex);
75       
76       Standard_Real        d2      = Pnt.SquareDistance(aPnt);
77       if(d2 < Dist) {
78         Dist          = d2;
79         anOppositePnt = Pnt;
80         param.Coord(U, V);
81       }
82     }
83     Dist = sqrt(Dist);
84     return Standard_True;
85   }
86
87   // Final result.
88   anOppositePnt = ext.Point(intvalue);
89   ext.Parameter(intvalue,U,V);
90
91   return Standard_True;
92 }
93
94
95
96 //=======================================================================
97 //function : BRepPrimAPI_MakeHalfSpace
98 //purpose  : 
99 //=======================================================================
100
101 BRepPrimAPI_MakeHalfSpace::BRepPrimAPI_MakeHalfSpace(const TopoDS_Face& Face,
102                                              const gp_Pnt&      RefPnt)
103 {
104   // Set the flag is <IsDone> to False.
105   NotDone();
106
107   TopoDS_Shell Shell;
108
109 //  gp_Pnt CurPnt, MinPnt;
110   gp_Pnt MinPnt;
111   Standard_Real U, V;
112
113   Standard_Real MinDist;
114   if (FindExtrema(RefPnt,Face,MinDist,MinPnt,U,V)) {
115     BRep_Builder myBuilder;
116     myBuilder.MakeShell(Shell);
117     myBuilder.Add(Shell,Face);
118     
119     // Normal, scalair product and direction.
120     Standard_Real Prec = gp::Resolution();
121 //    BRepLProp_SLProps Props(BRepAdaptor_Surface(Face),U,V,2,Prec);
122     BRepLProp_SLProps Props = BRepLProp_SLProps(BRepAdaptor_Surface(Face),U,V,2,Prec);
123     gp_Dir Normale    = Props.Normal();
124     gp_Dir OppRef(RefPnt.XYZ()-MinPnt.XYZ());
125     Standard_Real Sca = Normale*OppRef;
126     
127     // Construction of the open solid.
128     myBuilder.MakeSolid(mySolid);
129     if (Sca > 0.) {
130       // Same directions: inverted case.
131       Shell.Reverse();
132     }
133     
134     myBuilder.Add(mySolid,Shell);
135     Done();
136   }
137 }
138
139
140 //=======================================================================
141 //function : BRepPrimAPI_MakeHalfSpace
142 //purpose  : 
143 //=======================================================================
144
145 BRepPrimAPI_MakeHalfSpace::BRepPrimAPI_MakeHalfSpace(const TopoDS_Shell& Shell,
146                                              const gp_Pnt&       RefPnt)
147 {
148   // Set the flag is <IsDone> to False.
149   NotDone();
150
151   gp_Pnt CurPnt, MinPnt;
152   TopoDS_Face CurFace, MinFace;
153   Standard_Real MinDist = RealLast();
154   Standard_Real CurDist, U, V, MinU=0, MinV=0;
155
156   // Find the point of the skin closest to the reference point.
157   Standard_Boolean YaExt = Standard_False;
158
159   TopoDS_Shell aShell = Shell;
160   TopExp_Explorer Exp(aShell,TopAbs_FACE);
161   while (Exp.More()) {
162     CurFace = TopoDS::Face(Exp.Current());
163     if ( FindExtrema(RefPnt,CurFace,CurDist,CurPnt,U,V)) {
164       YaExt = Standard_True;
165       if (CurDist < MinDist) {
166         MinDist = CurDist;
167         MinPnt  = CurPnt;
168         MinU    = U;
169         MinV    = V;
170         MinFace = CurFace;
171       }
172     }
173     Exp.Next();
174   }
175
176   if ( YaExt) {
177     // Normal, scalar product and direction.
178     BRep_Builder myBuilder;
179     Standard_Real Prec = gp::Resolution();
180 //    BRepLProp_SLProps Props(BRepAdaptor_Surface(MinFace),MinU,MinV,2,Prec);
181     BRepLProp_SLProps Props = BRepLProp_SLProps(BRepAdaptor_Surface(MinFace),MinU,MinV,2,Prec);
182     gp_Dir Normale    = Props.Normal();
183     gp_Dir OppRef(RefPnt.XYZ()-MinPnt.XYZ());
184     Standard_Real Sca = Normale*OppRef;
185     
186     // Construction of the open solid.
187     myBuilder.MakeSolid(mySolid);
188     if (Sca > 0.) {
189       // Same directions: inverted case.
190       aShell.Reverse();
191     }
192     myBuilder.Add(mySolid,aShell);
193     Done();
194   }
195 }
196
197
198 //=======================================================================
199 //function : Solid
200 //purpose  : 
201 //=======================================================================
202
203 const TopoDS_Solid& BRepPrimAPI_MakeHalfSpace::Solid() const
204 {
205   StdFail_NotDone_Raise_if( !IsDone(), "BRepPrimAPI_MakeHalfSpace::Solid");
206   return mySolid;
207 }
208
209
210
211 //=======================================================================
212 //function : TopoDS_Solid
213 //purpose  : 
214 //=======================================================================
215
216 BRepPrimAPI_MakeHalfSpace::operator TopoDS_Solid() const
217 {
218   return Solid();
219 }
220
221