0031866: Documentation - add description to Graphic3d_NameOfMaterial enumeration...
[occt.git] / samples / ios / UIKitSample / UIKitSample / OcctViewer.mm
CommitLineData
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// =======================================================================
41OcctViewer::OcctViewer()
42{
43 myDoc = new OcctDocument();
44}
45
46// =======================================================================
47// function : ~OcctViewer
48// purpose :
49// =======================================================================
50OcctViewer::~OcctViewer()
51{
52 //
53}
54
55// =======================================================================
56// function : release
57// purpose :
58// =======================================================================
59void 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// =======================================================================
76bool 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// =======================================================================
126void OcctViewer::FitAll()
127{
128 if (!myView.IsNull())
129 {
130 myView->FitAll();
131 myView->ZFitAll();
132 }
133}
134
135// =======================================================================
136// function : StartRotation
137// purpose :
138// =======================================================================
139void 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// =======================================================================
151void 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// =======================================================================
163void 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// =======================================================================
175void 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// =======================================================================
197void 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// =======================================================================
211bool 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// =======================================================================
292void 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 {
a966542b 319 anAis = new CafShapePrs (aRefLabel, theParentStyle, Graphic3d_NameOfMaterial_ShinyPlastified);
a9bdd54d 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// =======================================================================
365void 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// =======================================================================
389void OcctViewer::clearContext ()
390{
391 if (!myContext.IsNull())
392 {
393 myContext->ClearSelected(Standard_False);
394 myContext->RemoveAll(Standard_False);
395 }
396}