0023625: New functionality building reflect lines on a shape
[occt.git] / src / HLRBRep / HLRBRep_HLRToShape.cxx
1 // Created on: 1993-10-11
2 // Created by: Christophe MARION
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <HLRBRep_HLRToShape.ixx>
23 #include <TopoDS.hxx>
24 #include <TopExp_Explorer.hxx>
25 #include <TopTools_IndexedMapOfShape.hxx>
26 #include <BRep_Builder.hxx>
27 #include <HLRBRep.hxx>
28 #include <HLRBRep_Data.hxx>
29 #include <HLRBRep_ShapeBounds.hxx>
30 #include <HLRAlgo_EdgeIterator.hxx>
31
32 //=======================================================================
33 //function : HLRBRep_HLRToShape
34 //purpose  : 
35 //=======================================================================
36
37 HLRBRep_HLRToShape::HLRBRep_HLRToShape (const Handle(HLRBRep_Algo)& A) :
38 myAlgo(A)
39 {}
40
41 //=======================================================================
42 //function : InternalCompound
43 //purpose  : 
44 //=======================================================================
45
46 TopoDS_Shape 
47 HLRBRep_HLRToShape::InternalCompound (const Standard_Integer typ,
48                                       const Standard_Boolean visible,
49                                       const TopoDS_Shape& S,
50                                       const Standard_Boolean In3d)
51 {
52   Standard_Boolean added = Standard_False;
53   TopoDS_Shape Result;
54   Handle(HLRBRep_Data) DS = myAlgo->DataStructure();
55
56   if (!DS.IsNull()) {
57     DS->Projector().Scaled(Standard_True);
58     Standard_Integer e1 = 1;
59     Standard_Integer e2 = DS->NbEdges();
60     Standard_Integer f1 = 1;
61     Standard_Integer f2 = DS->NbFaces();
62     Standard_Boolean explor = Standard_False;
63 //    Standard_Boolean todraw;
64     if (!S.IsNull()) {
65       Standard_Integer v1,v2;
66       Standard_Integer index = myAlgo->Index(S);
67       if (index == 0) explor = Standard_True;
68       else            myAlgo->ShapeBounds(index).Bounds(v1,v2,e1,e2,f1,f2);
69     }
70     BRep_Builder B;
71     B.MakeCompound(TopoDS::Compound(Result));
72     HLRBRep_EdgeData* ed = &(DS->EDataArray().ChangeValue(e1 - 1));
73     
74     for (Standard_Integer ie = e1; ie <= e2; ie++) {
75       ed++;
76       if (ed->Selected() && !ed->Vertical()) {
77         ed->Used(Standard_False);
78         ed->HideCount(0);
79       }
80       else ed->Used(Standard_True);
81     }
82     if (explor) {
83       TopTools_IndexedMapOfShape& Edges = DS->EdgeMap();
84       TopTools_IndexedMapOfShape& Faces = DS->FaceMap();
85       TopExp_Explorer Exp;
86       
87       for (Exp.Init (S, TopAbs_FACE);
88            Exp.More();
89            Exp.Next()) {
90         Standard_Integer iface = Faces.FindIndex(Exp.Current());
91         if (iface != 0)
92           DrawFace(visible,typ,iface,DS,Result,added,In3d);
93       }
94       if (typ >= 3) {
95
96         for (Exp.Init (S, TopAbs_EDGE, TopAbs_FACE);
97              Exp.More();
98              Exp.Next()) {
99           Standard_Integer ie = Edges.FindIndex(Exp.Current());
100           if (ie != 0) {
101             HLRBRep_EdgeData& ed = DS->EDataArray().ChangeValue(ie);
102             if (!ed.Used()) {
103               DrawEdge(visible,Standard_False,typ,ed,Result,added,In3d);
104               ed.Used(Standard_True);
105             }
106           }
107         }
108       }
109     }
110     else {
111
112       for (Standard_Integer iface = f1; iface <= f2; iface++)
113         DrawFace(visible,typ,iface,DS,Result,added,In3d);
114
115       if (typ >= 3) {
116         HLRBRep_EdgeData* ed = &(DS->EDataArray().ChangeValue(e1 - 1));
117         
118         for (Standard_Integer ie = e1; ie <= e2; ie++) {
119           ed++;
120           if (!ed->Used()) {
121             DrawEdge(visible,Standard_False,typ,*ed,Result,added,In3d);
122             ed->Used(Standard_True);
123           }
124         }
125       }
126     }
127     DS->Projector().Scaled(Standard_False);
128   }
129   if (!added) Result = TopoDS_Shape();
130   return Result;
131 }
132
133 //=======================================================================
134 //function : DrawFace
135 //purpose  : 
136 //=======================================================================
137
138 void 
139 HLRBRep_HLRToShape::DrawFace (const Standard_Boolean visible,
140                               const Standard_Integer typ,
141                               const Standard_Integer iface,
142                               Handle(HLRBRep_Data)& DS,
143                               TopoDS_Shape& Result,
144                               Standard_Boolean& added,
145                               const Standard_Boolean In3d) const
146 {
147   HLRBRep_FaceIterator Itf;
148
149   for (Itf.InitEdge(DS->FDataArray().ChangeValue(iface));
150        Itf.MoreEdge();
151        Itf.NextEdge()) {               
152     Standard_Integer ie = Itf.Edge();
153     HLRBRep_EdgeData& edf = DS->EDataArray().ChangeValue(ie);
154     if (!edf.Used()) {
155       Standard_Boolean todraw;
156       if      (typ == 1) todraw =  Itf.IsoLine();
157       else if (typ == 2) //outlines
158       {
159         if (In3d)
160           todraw = Itf.Internal() || Itf.OutLine();
161         else
162           todraw =  Itf.Internal();
163       }
164       else if (typ == 3) todraw =  edf.Rg1Line() &&
165         !edf.RgNLine() && !Itf.OutLine();
166       else if (typ == 4) todraw =  edf.RgNLine() && !Itf.OutLine();
167       else               todraw =
168         !(Itf.IsoLine()  ||
169           Itf.Internal() ||
170           (edf.Rg1Line() && !Itf.OutLine()));
171
172        if (todraw) {
173          DrawEdge(visible,Standard_True,typ,edf,Result,added,In3d);
174         edf.Used(Standard_True);
175       }
176       else {
177         if((typ > 4 || typ == 2) && //sharp or outlines
178            (edf.Rg1Line() && !Itf.OutLine()))
179         {
180           Standard_Integer hc = edf.HideCount();
181           if(hc > 0) {
182             edf.Used(Standard_True);
183           }
184           else {
185             ++hc;
186             edf.HideCount(hc); //to try with another face
187           }
188         }
189         else {
190           edf.Used(Standard_True);
191         }
192       }
193     }
194   }
195 }
196
197 //=======================================================================
198 //function : DrawEdge
199 //purpose  : 
200 //=======================================================================
201
202 void 
203 HLRBRep_HLRToShape::DrawEdge (const Standard_Boolean visible,
204                               const Standard_Boolean inFace,
205                               const Standard_Integer typ,
206                               HLRBRep_EdgeData& ed,
207                               TopoDS_Shape& Result,
208                               Standard_Boolean& added,
209                               const Standard_Boolean In3d) const
210 {
211   Standard_Boolean todraw = Standard_False;
212   if      (inFace)   todraw = Standard_True;
213   else if (typ == 3) todraw = ed.Rg1Line() && !ed.RgNLine();
214   else if (typ == 4) todraw = ed.RgNLine();
215   else               todraw =!ed.Rg1Line();
216
217   if (todraw) {
218     Standard_Real sta,end;
219     Standard_ShortReal tolsta,tolend;
220     BRep_Builder B;
221     TopoDS_Edge E;
222     HLRAlgo_EdgeIterator It;
223     if (visible)
224     {
225       for (It.InitVisible(ed.Status()); It.MoreVisible(); It.NextVisible()) {
226         It.Visible(sta,tolsta,end,tolend);
227         if (!In3d)
228           E = HLRBRep::MakeEdge(ed.Geometry(),sta,end);
229         else
230           E = HLRBRep::MakeEdge3d(ed.Geometry(),sta,end);
231         if (!E.IsNull())
232         {
233           B.Add(Result,E);
234           added = Standard_True;
235         }
236       }
237     }
238     else
239     {
240       for (It.InitHidden(ed.Status()); It.MoreHidden(); It.NextHidden()) {
241         It.Hidden(sta,tolsta,end,tolend);
242         if (!In3d)
243           E = HLRBRep::MakeEdge(ed.Geometry(),sta,end);
244         else
245           E = HLRBRep::MakeEdge3d(ed.Geometry(),sta,end);
246         if (!E.IsNull())
247         {
248           B.Add(Result,E);
249           added = Standard_True;
250         }
251       }
252     }
253   }
254 }