a9bdd54d |
1 | // Copyright (c) 2017 OPEN CASCADE SAS |
2 | // |
3 | // This file is part of Open CASCADE Technology software library. |
4 | // |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
10 | // |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
13 | |
14 | #include "OcctViewer.h" |
15 | #include "OcctDocument.h" |
16 | |
17 | #include <AIS_ConnectedInteractive.hxx> |
18 | #include <AIS_Shape.hxx> |
19 | #include <Aspect_DisplayConnection.hxx> |
20 | #include <BRep_Builder.hxx> |
21 | #include <BRepMesh_IncrementalMesh.hxx> |
22 | #include <BRepTools.hxx> |
23 | #include <Cocoa_Window.hxx> |
24 | #include <Message.hxx> |
25 | #include <Message_Messenger.hxx> |
26 | #include <OpenGl_GraphicDriver.hxx> |
7f24b768 |
27 | #include <StdPrs_ToolTriangulatedShape.hxx> |
a9bdd54d |
28 | #include <Prs3d_Drawer.hxx> |
29 | #include <STEPControl_Reader.hxx> |
30 | #include <STEPCAFControl_Reader.hxx> |
31 | #include <TDF_Tool.hxx> |
32 | #include <TDF_ChildIterator.hxx> |
33 | #include <Transfer_TransientProcess.hxx> |
34 | #include <XSControl_TransferReader.hxx> |
35 | #include <XCAFDoc_DocumentTool.hxx> |
36 | |
37 | // ======================================================================= |
38 | // function : OcctViewer |
39 | // purpose : |
40 | // ======================================================================= |
41 | OcctViewer::OcctViewer() |
42 | { |
43 | myDoc = new OcctDocument(); |
44 | } |
45 | |
46 | // ======================================================================= |
47 | // function : ~OcctViewer |
48 | // purpose : |
49 | // ======================================================================= |
50 | OcctViewer::~OcctViewer() |
51 | { |
52 | // |
53 | } |
54 | |
55 | // ======================================================================= |
56 | // function : release |
57 | // purpose : |
58 | // ======================================================================= |
59 | void OcctViewer::release() |
60 | { |
61 | myContext.Nullify(); |
62 | if (!myView.IsNull()) |
63 | { |
64 | myView->Remove(); |
65 | } |
66 | myView.Nullify(); |
67 | myViewer.Nullify(); |
68 | |
69 | myDoc.Nullify(); |
70 | } |
71 | |
72 | // ======================================================================= |
73 | // function : InitViewer |
74 | // purpose : |
75 | // ======================================================================= |
76 | bool OcctViewer::InitViewer (UIView* theWin) |
77 | { |
78 | EAGLContext* aRendCtx = [EAGLContext currentContext]; |
79 | if (theWin == NULL || aRendCtx == NULL) |
80 | { |
81 | NSLog(@"Error: No active EAGL context!"); |
82 | release(); |
83 | return false; |
84 | } |
85 | |
86 | if (!myView.IsNull()) |
87 | { |
88 | myView->MustBeResized(); |
89 | myView->Invalidate(); |
90 | } |
91 | else |
92 | { |
93 | Handle(Aspect_DisplayConnection) aDisplayConnection = new Aspect_DisplayConnection(); |
94 | Handle(Graphic3d_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver(aDisplayConnection); |
95 | |
96 | // Create Viewer |
97 | myViewer = new V3d_Viewer(aGraphicDriver); |
98 | myViewer->SetDefaultLights(); |
99 | myViewer->SetLightOn(); |
100 | |
101 | // Create AIS context |
102 | myContext = new AIS_InteractiveContext(myViewer); |
103 | myContext->SetDisplayMode((int)AIS_DisplayMode::AIS_Shaded, false); |
104 | |
105 | myView = myViewer->CreateView(); |
106 | myView->TriedronDisplay (Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.20, V3d_ZBUFFER); |
107 | |
108 | Handle(Cocoa_Window) aCocoaWindow = new Cocoa_Window(theWin); |
109 | myView->SetWindow(aCocoaWindow, aRendCtx); |
110 | if (!aCocoaWindow->IsMapped()) |
111 | { |
112 | aCocoaWindow->Map(); |
113 | } |
114 | |
115 | myView->Redraw(); |
116 | myView->MustBeResized(); |
117 | } |
118 | |
119 | return true; |
120 | } |
121 | |
122 | // ======================================================================= |
123 | // function : FitAll |
124 | // purpose : |
125 | // ======================================================================= |
126 | void OcctViewer::FitAll() |
127 | { |
128 | if (!myView.IsNull()) |
129 | { |
130 | myView->FitAll(); |
131 | myView->ZFitAll(); |
132 | } |
133 | } |
134 | |
135 | // ======================================================================= |
136 | // function : StartRotation |
137 | // purpose : |
138 | // ======================================================================= |
139 | void OcctViewer::StartRotation(int theX, int theY) |
140 | { |
141 | if (!myView.IsNull()) |
142 | { |
143 | myView->StartRotation(theX, theY); |
144 | } |
145 | } |
146 | |
147 | // ======================================================================= |
148 | // function : Rotation |
149 | // purpose : |
150 | // ======================================================================= |
151 | void OcctViewer::Rotation(int theX, int theY) |
152 | { |
153 | if (!myView.IsNull()) |
154 | { |
155 | myView->Rotation(theX, theY); |
156 | } |
157 | } |
158 | |
159 | // ======================================================================= |
160 | // function : Pan |
161 | // purpose : |
162 | // ======================================================================= |
163 | void OcctViewer::Pan(int theX, int theY) |
164 | { |
165 | if (!myView.IsNull()) |
166 | { |
167 | myView->Pan(theX, theY, 1, Standard_False); |
168 | } |
169 | } |
170 | |
171 | // ======================================================================= |
172 | // function : Zoom |
173 | // purpose : |
174 | // ======================================================================= |
175 | void OcctViewer::Zoom(int theX, int theY, double theDelta) |
176 | { |
177 | if (!myView.IsNull()) |
178 | { |
179 | if (theX >=0 && theY >=0) |
180 | { |
181 | myView->StartZoomAtPoint(theX, theY); |
182 | myView->ZoomAtPoint(0, 0, (int) theDelta, (int) theDelta); |
183 | } |
184 | else |
185 | { |
186 | double aCoeff = Abs(theDelta) / 100.0 + 1.0; |
187 | aCoeff = theDelta > 0.0 ? aCoeff : 1.0 / aCoeff; |
188 | myView->SetZoom(aCoeff, Standard_True); |
189 | } |
190 | } |
191 | } |
192 | |
193 | // ======================================================================= |
194 | // function : Select |
195 | // purpose : |
196 | // ======================================================================= |
197 | void OcctViewer::Select(int theX, int theY) |
198 | { |
199 | if (!myContext.IsNull()) |
200 | { |
201 | myContext->ClearSelected(Standard_False); |
202 | myContext->MoveTo(theX, theY, myView, Standard_False); |
203 | myContext->Select(Standard_False); |
204 | } |
205 | } |
206 | |
207 | // ======================================================================= |
208 | // function : ImportSTEP |
209 | // purpose : |
210 | // ======================================================================= |
211 | bool OcctViewer::ImportSTEP(std::string theFilename) |
212 | { |
213 | // create a new document |
214 | myDoc->InitDoc(); |
215 | |
216 | STEPCAFControl_Reader aReader; |
217 | Handle(XSControl_WorkSession) aSession = aReader.Reader().WS(); |
218 | |
219 | try { |
220 | if (!aReader.ReadFile (theFilename.c_str())) |
221 | { |
222 | clearSession (aSession); |
223 | return false; |
224 | } |
225 | |
226 | if (!aReader.Transfer (myDoc->ChangeDocument())) |
227 | { |
228 | clearSession (aSession); |
229 | return false; |
230 | } |
231 | |
232 | clearSession(aSession); |
233 | } catch (Standard_Failure theFailure) { |
234 | Message::DefaultMessenger()->Send (TCollection_AsciiString ("Exception raised during STEP import\n[") |
235 | + theFailure.GetMessageString() + "]\n" + theFilename.c_str(), Message_Fail); |
236 | return false; |
237 | } |
238 | |
239 | Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (myDoc->Document()->Main()); |
240 | Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (myDoc->Document()->Main()); |
241 | |
242 | TDF_LabelSequence aLabels; |
243 | aShapeTool->GetFreeShapes (aLabels); |
244 | |
245 | // perform meshing explicitly |
246 | TopoDS_Compound aCompound; |
247 | BRep_Builder aBuildTool; |
248 | aBuildTool.MakeCompound (aCompound); |
249 | for (Standard_Integer aLabIter = 1; aLabIter <= aLabels.Length(); ++aLabIter) |
250 | { |
251 | TopoDS_Shape aShape; |
252 | const TDF_Label& aLabel = aLabels.Value (aLabIter); |
253 | if (XCAFDoc_ShapeTool::GetShape (aLabel, aShape)) |
254 | { |
255 | aBuildTool.Add (aCompound, aShape); |
256 | } |
257 | } |
258 | |
259 | Handle(Prs3d_Drawer) aDrawer = myContext->DefaultDrawer(); |
7f24b768 |
260 | Standard_Real aDeflection = StdPrs_ToolTriangulatedShape::GetDeflection (aCompound, aDrawer); |
a9bdd54d |
261 | if (!BRepTools::Triangulation (aCompound, aDeflection)) |
262 | { |
263 | BRepMesh_IncrementalMesh anAlgo; |
264 | anAlgo.ChangeParameters().Deflection = aDeflection; |
67441d0c |
265 | anAlgo.ChangeParameters().Angle = aDrawer->DeviationAngle(); |
a9bdd54d |
266 | anAlgo.ChangeParameters().InParallel = Standard_True; |
267 | anAlgo.SetShape (aCompound); |
268 | anAlgo.Perform(); |
269 | } |
270 | |
271 | // clear presentations |
272 | clearContext(); |
273 | |
274 | // create presentations |
275 | MapOfPrsForShapes aMapOfShapes; |
276 | XCAFPrs_Style aDefStyle; |
277 | aDefStyle.SetColorSurf (Quantity_NOC_GRAY65); |
278 | aDefStyle.SetColorCurv (Quantity_NOC_GRAY65); |
279 | for (Standard_Integer aLabIter = 1; aLabIter <= aLabels.Length(); ++aLabIter) |
280 | { |
281 | const TDF_Label& aLabel = aLabels.Value (aLabIter); |
282 | displayWithChildren (*aShapeTool, *aColorTool, aLabel, TopLoc_Location(), aDefStyle, "", aMapOfShapes); |
283 | } |
284 | |
285 | return true; |
286 | } |
287 | |
288 | // ======================================================================= |
289 | // function : displayWithChildren |
290 | // purpose : |
291 | // ======================================================================= |
292 | void OcctViewer::displayWithChildren (XCAFDoc_ShapeTool& theShapeTool, |
293 | XCAFDoc_ColorTool& theColorTool, |
294 | const TDF_Label& theLabel, |
295 | const TopLoc_Location& theParentTrsf, |
296 | const XCAFPrs_Style& theParentStyle, |
297 | const TCollection_AsciiString& theParentId, |
298 | MapOfPrsForShapes& theMapOfShapes) |
299 | { |
300 | TDF_Label aRefLabel = theLabel; |
301 | if (theShapeTool.IsReference (theLabel)) |
302 | { |
303 | theShapeTool.GetReferredShape (theLabel, aRefLabel); |
304 | } |
305 | |
306 | TCollection_AsciiString anEntry; |
307 | TDF_Tool::Entry (theLabel, anEntry); |
308 | if (!theParentId.IsEmpty()) |
309 | { |
310 | anEntry = theParentId + "\n" + anEntry; |
311 | } |
312 | anEntry += "."; |
313 | |
314 | if (!theShapeTool.IsAssembly (aRefLabel)) |
315 | { |
316 | Handle(AIS_InteractiveObject) anAis; |
317 | if (!theMapOfShapes.Find (aRefLabel, anAis)) |
318 | { |
319 | anAis = new CafShapePrs (aRefLabel, theParentStyle, Graphic3d_NOM_SHINY_PLASTIC); |
320 | theMapOfShapes.Bind (aRefLabel, anAis); |
321 | } |
322 | |
323 | Handle(TCollection_HAsciiString) anId = new TCollection_HAsciiString (anEntry); |
324 | Handle(AIS_ConnectedInteractive) aConnected = new AIS_ConnectedInteractive(); |
325 | aConnected->Connect (anAis, theParentTrsf.Transformation()); |
326 | aConnected->SetOwner (anId); |
327 | aConnected->SetLocalTransformation (theParentTrsf.Transformation()); |
328 | aConnected->SetHilightMode(1); |
329 | myContext->Display (aConnected, Standard_False); |
330 | return; |
331 | } |
332 | |
333 | XCAFPrs_Style aDefStyle = theParentStyle; |
334 | Quantity_Color aColor; |
335 | if (theColorTool.GetColor (aRefLabel, XCAFDoc_ColorGen, aColor)) |
336 | { |
337 | aDefStyle.SetColorCurv (aColor); |
338 | aDefStyle.SetColorSurf (aColor); |
339 | } |
340 | if (theColorTool.GetColor (aRefLabel, XCAFDoc_ColorSurf, aColor)) |
341 | { |
342 | aDefStyle.SetColorSurf (aColor); |
343 | } |
344 | if (theColorTool.GetColor (aRefLabel, XCAFDoc_ColorCurv, aColor)) |
345 | { |
346 | aDefStyle.SetColorCurv (aColor); |
347 | } |
348 | |
349 | for (TDF_ChildIterator childIter (aRefLabel); childIter.More(); childIter.Next()) |
350 | { |
351 | TDF_Label aLabel = childIter.Value(); |
352 | if (!aLabel.IsNull() |
353 | && (aLabel.HasAttribute() || aLabel.HasChild())) |
354 | { |
355 | TopLoc_Location aTrsf = theParentTrsf * theShapeTool.GetLocation (aLabel); |
356 | displayWithChildren (theShapeTool, theColorTool, aLabel, aTrsf, aDefStyle, anEntry, theMapOfShapes); |
357 | } |
358 | } |
359 | } |
360 | |
361 | // ======================================================================= |
362 | // function : clearSession |
363 | // purpose : |
364 | // ======================================================================= |
365 | void OcctViewer::clearSession (const Handle(XSControl_WorkSession)& theSession) |
366 | { |
367 | if (theSession.IsNull()) |
368 | { |
369 | return; |
370 | } |
371 | |
372 | Handle(Transfer_TransientProcess) aMapReader = theSession->TransferReader()->TransientProcess(); |
373 | if (!aMapReader.IsNull()) |
374 | { |
375 | aMapReader->Clear(); |
376 | } |
377 | |
378 | Handle(XSControl_TransferReader) aTransferReader = theSession->TransferReader(); |
379 | if (!aTransferReader.IsNull()) |
380 | { |
381 | aTransferReader->Clear(1); |
382 | } |
383 | } |
384 | |
385 | // ======================================================================= |
386 | // function : clearContext |
387 | // purpose : |
388 | // ======================================================================= |
389 | void OcctViewer::clearContext () |
390 | { |
391 | if (!myContext.IsNull()) |
392 | { |
393 | myContext->ClearSelected(Standard_False); |
394 | myContext->RemoveAll(Standard_False); |
395 | } |
396 | } |