1 // Copyright (c) 2017 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include "OcctViewer.h"
15 #include "OcctDocument.h"
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>
27 #include <StdPrs_ToolTriangulatedShape.hxx>
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>
37 // =======================================================================
38 // function : OcctViewer
40 // =======================================================================
41 OcctViewer::OcctViewer()
43 myDoc = new OcctDocument();
46 // =======================================================================
47 // function : ~OcctViewer
49 // =======================================================================
50 OcctViewer::~OcctViewer()
55 // =======================================================================
58 // =======================================================================
59 void OcctViewer::release()
72 // =======================================================================
73 // function : InitViewer
75 // =======================================================================
76 bool OcctViewer::InitViewer (UIView* theWin)
78 EAGLContext* aRendCtx = [EAGLContext currentContext];
79 if (theWin == NULL || aRendCtx == NULL)
81 NSLog(@"Error: No active EAGL context!");
88 myView->MustBeResized();
93 Handle(Aspect_DisplayConnection) aDisplayConnection = new Aspect_DisplayConnection();
94 Handle(Graphic3d_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver(aDisplayConnection);
97 myViewer = new V3d_Viewer(aGraphicDriver);
98 myViewer->SetDefaultLights();
99 myViewer->SetLightOn();
101 // Create AIS context
102 myContext = new AIS_InteractiveContext(myViewer);
103 myContext->SetDisplayMode((int)AIS_DisplayMode::AIS_Shaded, false);
105 myView = myViewer->CreateView();
106 myView->TriedronDisplay (Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.20, V3d_ZBUFFER);
108 Handle(Cocoa_Window) aCocoaWindow = new Cocoa_Window(theWin);
109 myView->SetWindow(aCocoaWindow, aRendCtx);
110 if (!aCocoaWindow->IsMapped())
116 myView->MustBeResized();
122 // =======================================================================
125 // =======================================================================
126 void OcctViewer::FitAll()
128 if (!myView.IsNull())
135 // =======================================================================
136 // function : StartRotation
138 // =======================================================================
139 void OcctViewer::StartRotation(int theX, int theY)
141 if (!myView.IsNull())
143 myView->StartRotation(theX, theY);
147 // =======================================================================
148 // function : Rotation
150 // =======================================================================
151 void OcctViewer::Rotation(int theX, int theY)
153 if (!myView.IsNull())
155 myView->Rotation(theX, theY);
159 // =======================================================================
162 // =======================================================================
163 void OcctViewer::Pan(int theX, int theY)
165 if (!myView.IsNull())
167 myView->Pan(theX, theY, 1, Standard_False);
171 // =======================================================================
174 // =======================================================================
175 void OcctViewer::Zoom(int theX, int theY, double theDelta)
177 if (!myView.IsNull())
179 if (theX >=0 && theY >=0)
181 myView->StartZoomAtPoint(theX, theY);
182 myView->ZoomAtPoint(0, 0, (int) theDelta, (int) theDelta);
186 double aCoeff = Abs(theDelta) / 100.0 + 1.0;
187 aCoeff = theDelta > 0.0 ? aCoeff : 1.0 / aCoeff;
188 myView->SetZoom(aCoeff, Standard_True);
193 // =======================================================================
196 // =======================================================================
197 void OcctViewer::Select(int theX, int theY)
199 if (!myContext.IsNull())
201 myContext->ClearSelected(Standard_False);
202 myContext->MoveTo(theX, theY, myView, Standard_False);
203 myContext->Select(Standard_False);
207 // =======================================================================
208 // function : ImportSTEP
210 // =======================================================================
211 bool OcctViewer::ImportSTEP(std::string theFilename)
213 // create a new document
216 STEPCAFControl_Reader aReader;
217 Handle(XSControl_WorkSession) aSession = aReader.Reader().WS();
220 if (!aReader.ReadFile (theFilename.c_str()))
222 clearSession (aSession);
226 if (!aReader.Transfer (myDoc->ChangeDocument()))
228 clearSession (aSession);
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);
239 Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (myDoc->Document()->Main());
240 Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (myDoc->Document()->Main());
242 TDF_LabelSequence aLabels;
243 aShapeTool->GetFreeShapes (aLabels);
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)
252 const TDF_Label& aLabel = aLabels.Value (aLabIter);
253 if (XCAFDoc_ShapeTool::GetShape (aLabel, aShape))
255 aBuildTool.Add (aCompound, aShape);
259 Handle(Prs3d_Drawer) aDrawer = myContext->DefaultDrawer();
260 Standard_Real aDeflection = StdPrs_ToolTriangulatedShape::GetDeflection (aCompound, aDrawer);
261 if (!BRepTools::Triangulation (aCompound, aDeflection))
263 BRepMesh_IncrementalMesh anAlgo;
264 anAlgo.ChangeParameters().Deflection = aDeflection;
265 anAlgo.ChangeParameters().Angle = aDrawer->DeviationAngle();
266 anAlgo.ChangeParameters().InParallel = Standard_True;
267 anAlgo.SetShape (aCompound);
271 // clear presentations
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)
281 const TDF_Label& aLabel = aLabels.Value (aLabIter);
282 displayWithChildren (*aShapeTool, *aColorTool, aLabel, TopLoc_Location(), aDefStyle, "", aMapOfShapes);
288 // =======================================================================
289 // function : displayWithChildren
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)
300 TDF_Label aRefLabel = theLabel;
301 if (theShapeTool.IsReference (theLabel))
303 theShapeTool.GetReferredShape (theLabel, aRefLabel);
306 TCollection_AsciiString anEntry;
307 TDF_Tool::Entry (theLabel, anEntry);
308 if (!theParentId.IsEmpty())
310 anEntry = theParentId + "\n" + anEntry;
314 if (!theShapeTool.IsAssembly (aRefLabel))
316 Handle(AIS_InteractiveObject) anAis;
317 if (!theMapOfShapes.Find (aRefLabel, anAis))
319 anAis = new CafShapePrs (aRefLabel, theParentStyle, Graphic3d_NOM_SHINY_PLASTIC);
320 theMapOfShapes.Bind (aRefLabel, anAis);
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);
333 XCAFPrs_Style aDefStyle = theParentStyle;
334 Quantity_Color aColor;
335 if (theColorTool.GetColor (aRefLabel, XCAFDoc_ColorGen, aColor))
337 aDefStyle.SetColorCurv (aColor);
338 aDefStyle.SetColorSurf (aColor);
340 if (theColorTool.GetColor (aRefLabel, XCAFDoc_ColorSurf, aColor))
342 aDefStyle.SetColorSurf (aColor);
344 if (theColorTool.GetColor (aRefLabel, XCAFDoc_ColorCurv, aColor))
346 aDefStyle.SetColorCurv (aColor);
349 for (TDF_ChildIterator childIter (aRefLabel); childIter.More(); childIter.Next())
351 TDF_Label aLabel = childIter.Value();
353 && (aLabel.HasAttribute() || aLabel.HasChild()))
355 TopLoc_Location aTrsf = theParentTrsf * theShapeTool.GetLocation (aLabel);
356 displayWithChildren (theShapeTool, theColorTool, aLabel, aTrsf, aDefStyle, anEntry, theMapOfShapes);
361 // =======================================================================
362 // function : clearSession
364 // =======================================================================
365 void OcctViewer::clearSession (const Handle(XSControl_WorkSession)& theSession)
367 if (theSession.IsNull())
372 Handle(Transfer_TransientProcess) aMapReader = theSession->TransferReader()->TransientProcess();
373 if (!aMapReader.IsNull())
378 Handle(XSControl_TransferReader) aTransferReader = theSession->TransferReader();
379 if (!aTransferReader.IsNull())
381 aTransferReader->Clear(1);
385 // =======================================================================
386 // function : clearContext
388 // =======================================================================
389 void OcctViewer::clearContext ()
391 if (!myContext.IsNull())
393 myContext->ClearSelected(Standard_False);
394 myContext->RemoveAll(Standard_False);