#include #include // include required OCCT headers #include #include #include //for OCC graphic #include #include #include #include #include #include #include //for object display #include #include #include #include //topology #include #include //brep tools #include #include // iges I/E #include #include #include #include #include //step I/E #include #include //for stl export #include //for vrml export #include //wrapper of pure C++ classes to ref classes #include #include // list of required OCCT libraries #pragma comment(lib, "TKernel.lib") #pragma comment(lib, "TKMath.lib") #pragma comment(lib, "TKBRep.lib") #pragma comment(lib, "TKXSBase.lib") #pragma comment(lib, "TKService.lib") #pragma comment(lib, "TKV3d.lib") #pragma comment(lib, "TKOpenGl.lib") #pragma comment(lib, "TKD3dHost.lib") #pragma comment(lib, "TKIGES.lib") #pragma comment(lib, "TKSTEP.lib") #pragma comment(lib, "TKStl.lib") #pragma comment(lib, "TKVrml.lib") #pragma comment(lib, "TKLCAF.lib") #pragma comment(lib, "D3D9.lib") //! Auxiliary tool for converting C# string into UTF-8 string. static TCollection_AsciiString toAsciiString (String^ theString) { if (theString == nullptr) { return TCollection_AsciiString(); } pin_ptr aPinChars = PtrToStringChars (theString); const wchar_t* aWCharPtr = aPinChars; if (aWCharPtr == NULL || *aWCharPtr == L'\0') { return TCollection_AsciiString(); } return TCollection_AsciiString (aWCharPtr); } /// /// Proxy class encapsulating calls to OCCT C++ classes within /// C++/CLI class visible from .Net (CSharp) /// public ref class OCCTProxyD3D { public: OCCTProxyD3D() {} // ============================================ // Viewer functionality // ============================================ /// ///Initialize a viewer /// /// System.IntPtr that contains the window handle (HWND) of the control bool InitViewer() { myGraphicDriver() = new D3DHost_GraphicDriver(); myGraphicDriver()->ChangeOptions().buffersNoSwap = true; //myGraphicDriver()->ChangeOptions().contextDebug = true; myViewer() = new V3d_Viewer (myGraphicDriver()); myViewer()->SetDefaultLights(); myViewer()->SetLightOn(); myView() = myViewer()->CreateView(); static Handle(WNT_WClass) aWClass = new WNT_WClass ("OCC_Viewer", NULL, CS_OWNDC); Handle(WNT_Window) aWNTWindow = new WNT_Window ("OCC_Viewer", aWClass, WS_POPUP, 64, 64, 64, 64); aWNTWindow->SetVirtual (Standard_True); myView()->SetWindow(aWNTWindow); myAISContext() = new AIS_InteractiveContext (myViewer()); myAISContext()->UpdateCurrentViewer(); myView()->MustBeResized(); return true; } /// Resizes custom FBO for Direct3D output. System::IntPtr ResizeBridgeFBO (int theWinSizeX, int theWinSizeY) { Handle(WNT_Window) aWNTWindow = Handle(WNT_Window)::DownCast (myView()->Window()); aWNTWindow->SetPos (0, 0, theWinSizeX, theWinSizeY); myView()->MustBeResized(); myView()->Invalidate(); return System::IntPtr(Handle(D3DHost_View)::DownCast (myView()->View())->D3dColorSurface()); } /// /// Make dump of current view to file /// /// Name of dump file bool Dump (const TCollection_AsciiString& theFileName) { if (myView().IsNull()) { return false; } myView()->Redraw(); return myView()->Dump (theFileName.ToCString()) != Standard_False; } /// ///Redraw view /// void RedrawView() { if (!myView().IsNull()) { myView()->Redraw(); } } /// ///Update view /// void UpdateView(void) { if (!myView().IsNull()) { myView()->MustBeResized(); } } /// ///Set computed mode in false /// void SetDegenerateModeOn() { if (!myView().IsNull()) { myView()->SetComputedMode (Standard_False); myView()->Redraw(); } } /// ///Set computed mode in true /// void SetDegenerateModeOff() { if (!myView().IsNull()) { myView()->SetComputedMode (Standard_True); myView()->Redraw(); } } /// ///Fit all /// void WindowFitAll (int theXmin, int theYmin, int theXmax, int theYmax) { if (!myView().IsNull()) { myView()->WindowFitAll (theXmin, theYmin, theXmax, theYmax); } } /// ///Current place of window /// /// Current zoom void Place (int theX, int theY, float theZoomFactor) { Standard_Real aZoomFactor = theZoomFactor; if (!myView().IsNull()) { myView()->Place (theX, theY, aZoomFactor); } } /// ///Set Zoom /// void Zoom (int theX1, int theY1, int theX2, int theY2) { if (!myView().IsNull()) { myView()->Zoom (theX1, theY1, theX2, theY2); } } /// ///Set Pan /// void Pan (int theX, int theY) { if (!myView().IsNull()) { myView()->Pan (theX, theY); } } /// ///Rotation /// void Rotation (int theX, int theY) { if (!myView().IsNull()) { myView()->Rotation (theX, theY); } } /// ///Start rotation /// void StartRotation (int theX, int theY) { if (!myView().IsNull()) { myView()->StartRotation (theX, theY); } } /// ///Select by rectangle /// void Select (int theX1, int theY1, int theX2, int theY2) { if (!myAISContext().IsNull()) { myAISContext()->SelectRectangle (Graphic3d_Vec2i (theX1, theY1), Graphic3d_Vec2i (theX2, theY2), myView()); myAISContext()->UpdateCurrentViewer(); } } /// ///Select by click /// void Select() { if (!myAISContext().IsNull()) { myAISContext()->SelectDetected(); myAISContext()->UpdateCurrentViewer(); } } /// ///Move view /// void MoveTo (int theX, int theY) { if (!myAISContext().IsNull() && !myView().IsNull()) { myAISContext()->MoveTo (theX, theY, myView(), Standard_True); } } /// ///Select by rectangle with pressed "Shift" key /// void ShiftSelect (int theX1, int theY1, int theX2, int theY2) { if (!myAISContext().IsNull() && !myView().IsNull()) { myAISContext()->SelectRectangle (Graphic3d_Vec2i (theX1, theY1), Graphic3d_Vec2i (theX2, theY2), myView(), AIS_SelectionScheme_XOR); myAISContext()->UpdateCurrentViewer(); } } /// ///Select by "Shift" key /// void ShiftSelect() { if (!myAISContext().IsNull()) { myAISContext()->SelectDetected (AIS_SelectionScheme_XOR); myAISContext()->UpdateCurrentViewer(); } } /// ///Set background color /// void BackgroundColor (int& theRed, int& theGreen, int& theBlue) { if (!myView().IsNull()) { Quantity_Color aColor = myView()->BackgroundColor(); theRed = (int )aColor.Red() * 255; theGreen = (int )aColor.Green() * 255; theBlue = (int )aColor.Blue() * 255; } } /// ///Get background color Red /// int GetBGColR() { int anRgb[3]; BackgroundColor (anRgb[0], anRgb[1], anRgb[2]); return anRgb[0]; } /// ///Get background color Green /// int GetBGColG() { int anRgb[3]; BackgroundColor (anRgb[0], anRgb[1], anRgb[2]); return anRgb[1]; } /// ///Get background color Blue /// int GetBGColB() { int anRgb[3]; BackgroundColor (anRgb[0], anRgb[1], anRgb[2]); return anRgb[2]; } /// ///Update current viewer /// void UpdateCurrentViewer() { if (!myAISContext().IsNull()) { myAISContext()->UpdateCurrentViewer(); } } /// ///Front side /// void FrontView() { if (!myView().IsNull()) { myView()->SetProj (V3d_Yneg); } } /// ///Top side /// void TopView() { if (!myView().IsNull()) { myView()->SetProj (V3d_Zpos); } } /// ///Left side /// void LeftView() { if (!myView().IsNull()) { myView()->SetProj (V3d_Xneg); } } /// ///Back side /// void BackView() { if (!myView().IsNull()) { myView()->SetProj (V3d_Ypos); } } /// ///Right side /// void RightView() { if (!myView().IsNull()) { myView()->SetProj (V3d_Xpos); } } /// ///Bottom side /// void BottomView() { if (!myView().IsNull()) { myView()->SetProj (V3d_Zneg); } } /// ///Axo side /// void AxoView() { if (!myView().IsNull()) { myView()->SetProj (V3d_XposYnegZpos); } } /// ///Scale /// float Scale() { return myView().IsNull() ? -1.0f : float(myView()->Scale()); } /// ///Zoom in all view /// void ZoomAllView() { if (!myView().IsNull()) { myView()->FitAll(); myView()->ZFitAll(); } } /// ///Reset view /// void Reset() { if (!myView().IsNull()) { myView()->Reset(); } } /// ///Set display mode of objects /// /// Set current mode void SetDisplayMode (int theMode) { if (myAISContext().IsNull()) { return; } AIS_DisplayMode aCurrentMode = theMode == 0 ? AIS_WireFrame : AIS_Shaded; if (myAISContext()->NbSelected() == 0) { myAISContext()->SetDisplayMode (aCurrentMode, Standard_False); } else { for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { myAISContext()->SetDisplayMode (myAISContext()->SelectedInteractive(), theMode, Standard_False); } } myAISContext()->UpdateCurrentViewer(); } /// ///Set color /// void SetColor (int theR, int theG, int theB) { if (myAISContext().IsNull()) { return; } Quantity_Color aCol (theR / 255.0, theG / 255.0, theB / 255.0, Quantity_TOC_RGB); for (; myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { myAISContext()->SetColor (myAISContext()->SelectedInteractive(), aCol, false); } myAISContext()->UpdateCurrentViewer(); } /// ///Get object color red /// int GetObjColR() { int anRgb[3]; ObjectColor (anRgb[0], anRgb[1], anRgb[2]); return anRgb[0]; } /// ///Get object color green /// int GetObjColG() { int anRgb[3]; ObjectColor (anRgb[0], anRgb[1], anRgb[2]); return anRgb[1]; } /// ///Get object color blue /// int GetObjColB() { int anRgb[3]; ObjectColor (anRgb[0], anRgb[1], anRgb[2]); return anRgb[2]; } /// ///Get object color R/G/B /// void ObjectColor (int& theRed, int& theGreen, int& theBlue) { if (myAISContext().IsNull()) { return; } theRed = 255; theGreen = 255; theBlue = 255; myAISContext()->InitSelected(); if (!myAISContext()->MoreSelected()) { return; } Handle(AIS_InteractiveObject) aCurrent = myAISContext()->SelectedInteractive(); if (aCurrent->HasColor()) { Quantity_Color anObjCol; myAISContext()->Color (aCurrent, anObjCol); theRed = int(anObjCol.Red() * 255.0); theGreen = int(anObjCol.Green() * 255.0); theBlue = int(anObjCol.Blue() * 255.0); } } /// ///Set background color R/G/B /// void SetBackgroundColor (int theRed, int theGreen, int theBlue) { if (!myView().IsNull()) { myView()->SetBackgroundColor (Quantity_TOC_RGB, theRed / 255.0, theGreen / 255.0, theBlue / 255.0); } } /// ///Erase objects /// void EraseObjects() { if (myAISContext().IsNull()) { return; } myAISContext()->EraseSelected (Standard_False); myAISContext()->ClearSelected (Standard_True); } /// ///Get version /// float GetOCCVersion() { return (float )OCC_VERSION; } /// ///set material /// void SetMaterial (int theMaterial) { if (myAISContext().IsNull()) { return; } for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { myAISContext()->SetMaterial (myAISContext()->SelectedInteractive(), (Graphic3d_NameOfMaterial )theMaterial, Standard_False); } myAISContext()->UpdateCurrentViewer(); } /// ///set transparency /// void SetTransparency (int theTrans) { if (myAISContext().IsNull()) { return; } for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { myAISContext()->SetTransparency (myAISContext()->SelectedInteractive(), ((Standard_Real )theTrans) / 10.0, Standard_False); } myAISContext()->UpdateCurrentViewer(); } /// ///Return true if object is selected /// bool IsObjectSelected() { if (myAISContext().IsNull()) { return false; } myAISContext()->InitSelected(); return myAISContext()->MoreSelected() != Standard_False; } /// ///Return display mode /// int DisplayMode() { if (myAISContext().IsNull()) { return -1; } bool isOneOrMoreInShading = false; bool isOneOrMoreInWireframe = false; for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { if (myAISContext()->IsDisplayed (myAISContext()->SelectedInteractive(), AIS_Shaded)) { isOneOrMoreInShading = true; } if (myAISContext()->IsDisplayed (myAISContext()->SelectedInteractive(), AIS_WireFrame)) { isOneOrMoreInWireframe = true; } } if (isOneOrMoreInShading && isOneOrMoreInWireframe) { return 10; } else if (isOneOrMoreInShading) { return 1; } else if (isOneOrMoreInWireframe) { return 0; } return -1; } /// ///Set AISContext /// bool SetAISContext (OCCTProxyD3D^ theViewer) { this->myAISContext() = theViewer->GetContext(); if (myAISContext().IsNull()) { return false; } return true; } /// ///Get AISContext /// Handle(AIS_InteractiveContext) GetContext() { return myAISContext(); } public: // ============================================ // Import / export functionality // ============================================ /// ///Import BRep file /// /// Name of import file bool ImportBrep (System::String^ theFileName) { return ImportBrep (toAsciiString (theFileName)); } /// ///Import BRep file /// /// Name of import file bool ImportBrep (const TCollection_AsciiString& theFileName) { TopoDS_Shape aShape; BRep_Builder aBuilder; if (!BRepTools::Read (aShape, theFileName.ToCString(), aBuilder)) { return false; } Handle(AIS_Shape) aPrs = new AIS_Shape (aShape); myAISContext()->SetMaterial (aPrs, Graphic3d_NameOfMaterial_Gold, Standard_False); myAISContext()->SetDisplayMode(aPrs, AIS_Shaded, Standard_False); myAISContext()->Display (aPrs, Standard_True); return true; } /// ///Import Step file /// /// Name of import file bool ImportStep (const TCollection_AsciiString& theFileName) { STEPControl_Reader aReader; if (aReader.ReadFile (theFileName.ToCString()) != IFSelect_RetDone) { return false; } bool isFailsonly = false; aReader.PrintCheckLoad( isFailsonly, IFSelect_ItemsByEntity ); int aNbRoot = aReader.NbRootsForTransfer(); aReader.PrintCheckTransfer (isFailsonly, IFSelect_ItemsByEntity); for (Standard_Integer aRootIter = 1; aRootIter <= aNbRoot; ++aRootIter) { aReader.TransferRoot (aRootIter); int aNbShap = aReader.NbShapes(); if (aNbShap > 0) { for (int aShapeIter = 1; aShapeIter <= aNbShap; ++aShapeIter) { myAISContext()->Display (new AIS_Shape (aReader.Shape (aShapeIter)), Standard_False); } myAISContext()->UpdateCurrentViewer(); } } return true; } /// ///Import Iges file /// /// Name of import file bool ImportIges (const TCollection_AsciiString& theFileName) { IGESControl_Reader aReader; if (aReader.ReadFile (theFileName.ToCString()) != IFSelect_RetDone) { return false; } aReader.TransferRoots(); TopoDS_Shape aShape = aReader.OneShape(); myAISContext()->Display (new AIS_Shape (aShape), Standard_False); myAISContext()->UpdateCurrentViewer(); return true; } /// ///Export BRep file /// /// Name of export file bool ExportBRep (const TCollection_AsciiString& theFileName) { myAISContext()->InitSelected(); if (!myAISContext()->MoreSelected()) { return false; } Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive()); return !anIS.IsNull() && BRepTools::Write (anIS->Shape(), theFileName.ToCString()); } /// ///Export Step file /// /// Name of export file bool ExportStep (const TCollection_AsciiString& theFileName) { STEPControl_StepModelType aType = STEPControl_AsIs; STEPControl_Writer aWriter; for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive()); if (anIS.IsNull()) { return false; } TopoDS_Shape aShape = anIS->Shape(); if (aWriter.Transfer (aShape, aType) != IFSelect_RetDone) { return false; } } return aWriter.Write (theFileName.ToCString()) == IFSelect_RetDone; } /// ///Export Iges file /// /// Name of export file bool ExportIges (const TCollection_AsciiString& theFileName) { IGESControl_Controller::Init(); IGESControl_Writer aWriter (Interface_Static::CVal ("XSTEP.iges.unit"), Interface_Static::IVal ("XSTEP.iges.writebrep.mode")); for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive()); if (anIS.IsNull()) { return false; } aWriter.AddShape (anIS->Shape()); } aWriter.ComputeModel(); return aWriter.Write (theFileName.ToCString()) != Standard_False; } /// ///Export Vrml file /// /// Name of export file bool ExportVrml (const TCollection_AsciiString& theFileName) { TopoDS_Compound aRes; BRep_Builder aBuilder; aBuilder.MakeCompound (aRes); for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive()); if (anIS.IsNull()) { return false; } aBuilder.Add (aRes, anIS->Shape()); } VrmlAPI_Writer aWriter; aWriter.Write (aRes, theFileName.ToCString()); return true; } /// ///Export Stl file /// /// Name of export file bool ExportStl (const TCollection_AsciiString& theFileName) { TopoDS_Compound aComp; BRep_Builder aBuilder; aBuilder.MakeCompound (aComp); for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive()); if (anIS.IsNull()) { return false; } aBuilder.Add (aComp, anIS->Shape()); } StlAPI_Writer aWriter; aWriter.Write (aComp, theFileName.ToCString()); return true; } /// ///Define which Import/Export function must be called /// /// Name of Import/Export file /// Determines format of Import/Export file /// Determines is Import or not bool TranslateModel (System::String^ theFileName, int theFormat, bool theIsImport) { bool isResult = false; const TCollection_AsciiString aFilename = toAsciiString (theFileName); if (theIsImport) { switch (theFormat) { case 0: isResult = ImportBrep (aFilename); break; case 1: isResult = ImportStep (aFilename); break; case 2: isResult = ImportIges (aFilename); break; } } else { switch (theFormat) { case 0: isResult = ExportBRep (aFilename); break; case 1: isResult = ExportStep (aFilename); break; case 2: isResult = ExportIges (aFilename); break; case 3: isResult = ExportVrml (aFilename); break; case 4: isResult = ExportStl (aFilename); break; case 5: isResult = Dump (aFilename); break; } } return isResult; } /// ///Initialize OCCTProxyD3D /// void InitOCCTProxy() { myGraphicDriver().Nullify(); myViewer().Nullify(); myView().Nullify(); myAISContext().Nullify(); } private: NCollection_Haft myViewer; NCollection_Haft myView; NCollection_Haft myAISContext; NCollection_Haft myGraphicDriver; };