// include required OCCT headers #include <Standard_Version.hxx> #include <Message_ProgressIndicator.hxx> //for OCC graphic #include <Aspect_DisplayConnection.hxx> #include <WNT_Window.hxx> #include <OpenGl_GraphicDriver.hxx> //for object display #include <V3d_Viewer.hxx> #include <V3d_View.hxx> #include <AIS_InteractiveContext.hxx> #include <AIS_Shape.hxx> //topology #include <TopoDS_Shape.hxx> #include <TopoDS_Compound.hxx> //brep tools #include <BRep_Builder.hxx> #include <BRepTools.hxx> // iges I/E #include <IGESControl_Reader.hxx> #include <IGESControl_Controller.hxx> #include <IGESControl_Writer.hxx> #include <IFSelect_ReturnStatus.hxx> #include <Interface_Static.hxx> //step I/E #include <STEPControl_Reader.hxx> #include <STEPControl_Writer.hxx> //for stl export #include <StlAPI_Writer.hxx> //for vrml export #include <VrmlAPI_Writer.hxx> //wrapper of pure C++ classes to ref classes #include <NCollection_Haft.h> #include <vcclr.h> // 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, "TKIGES.lib") #pragma comment(lib, "TKSTEP.lib") #pragma comment(lib, "TKStl.lib") #pragma comment(lib, "TKVrml.lib") #pragma comment(lib, "TKLCAF.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<const wchar_t> aPinChars = PtrToStringChars (theString); const wchar_t* aWCharPtr = aPinChars; if (aWCharPtr == NULL || *aWCharPtr == L'\0') { return TCollection_AsciiString(); } return TCollection_AsciiString (aWCharPtr); } /// <summary> /// Proxy class encapsulating calls to OCCT C++ classes within /// C++/CLI class visible from .Net (CSharp) /// </summary> public ref class OCCTProxy { public: // ============================================ // Viewer functionality // ============================================ /// <summary> ///Initialize a viewer /// </summary> /// <param name="theWnd">System.IntPtr that contains the window handle (HWND) of the control</param> bool InitViewer(System::IntPtr theWnd) { try { Handle(Aspect_DisplayConnection) aDisplayConnection; myGraphicDriver() = new OpenGl_GraphicDriver (aDisplayConnection); } catch (Standard_Failure) { return false; } myViewer() = new V3d_Viewer (myGraphicDriver()); myViewer()->SetDefaultLights(); myViewer()->SetLightOn(); myView() = myViewer()->CreateView(); Handle(WNT_Window) aWNTWindow = new WNT_Window (reinterpret_cast<HWND> (theWnd.ToPointer())); myView()->SetWindow(aWNTWindow); if (!aWNTWindow->IsMapped()) { aWNTWindow->Map(); } myAISContext() = new AIS_InteractiveContext( myViewer() ); myAISContext()->UpdateCurrentViewer(); myView()->Redraw(); myView()->MustBeResized(); return true; } /// <summary> /// Make dump of current view to file /// </summary> /// <param name="theFileName">Name of dump file</param> bool Dump(const TCollection_AsciiString& theFileName) { if (myView().IsNull()) { return false; } myView()->Redraw(); return myView()->Dump(theFileName.ToCString()) != Standard_False; } /// <summary> ///Redraw view /// </summary> void RedrawView(void) { if (!myView().IsNull()) { myView()->Redraw(); } } /// <summary> ///Update view /// </summary> void UpdateView(void) { if (!myView().IsNull()) { myView()->MustBeResized(); } } /// <summary> ///Set computed mode in false /// </summary> void SetDegenerateModeOn(void) { if (!myView().IsNull()) { myView()->SetComputedMode (Standard_False); myView()->Redraw(); } } /// <summary> ///Set computed mode in true /// </summary> void SetDegenerateModeOff(void) { if (!myView().IsNull()) { myView()->SetComputedMode (Standard_True); myView()->Redraw(); } } /// <summary> ///Fit all /// </summary> void WindowFitAll(int theXmin, int theYmin, int theXmax, int theYmax) { if (!myView().IsNull()) { myView()->WindowFitAll(theXmin, theYmin, theXmax, theYmax); } } /// <summary> ///Current place of window /// </summary> /// <param name="theZoomFactor">Current zoom</param> void Place(int theX, int theY, float theZoomFactor) { Standard_Real aZoomFactor = theZoomFactor; if (!myView().IsNull()) { myView()->Place(theX, theY, aZoomFactor); } } /// <summary> ///Set Zoom /// </summary> void Zoom(int theX1, int theY1, int theX2, int theY2) { if (!myView().IsNull()) { myView()->Zoom(theX1, theY1, theX2, theY2); } } /// <summary> ///Set Pan /// </summary> void Pan(int theX, int theY) { if (!myView().IsNull()) { myView()->Pan(theX, theY); } } /// <summary> ///Rotation /// </summary> void Rotation(int theX, int theY) { if (!myView().IsNull()) { myView()->Rotation(theX, theY); } } /// <summary> ///Start rotation /// </summary> void StartRotation(int theX, int theY) { if (!myView().IsNull()) { myView()->StartRotation(theX, theY); } } /// <summary> ///Select by rectangle /// </summary> void Select(int theX1, int theY1, int theX2, int theY2) { if (!myAISContext().IsNull()) { myAISContext()->Select (theX1, theY1, theX2, theY2, myView(), Standard_True); } } /// <summary> ///Select by click /// </summary> void Select(void) { if (!myAISContext().IsNull()) { myAISContext()->Select (Standard_True); } } /// <summary> ///Move view /// </summary> void MoveTo(int theX, int theY) { if ((!myAISContext().IsNull()) && (!myView().IsNull())) { myAISContext()->MoveTo (theX, theY, myView(), Standard_True); } } /// <summary> ///Select by rectangle with pressed "Shift" key /// </summary> void ShiftSelect(int theX1, int theY1, int theX2, int theY2) { if ((!myAISContext().IsNull()) && (!myView().IsNull())) { myAISContext()->ShiftSelect (theX1, theY1, theX2, theY2, myView(), Standard_True); } } /// <summary> ///Select by "Shift" key /// </summary> void ShiftSelect(void) { if (!myAISContext().IsNull()) { myAISContext()->ShiftSelect (Standard_True); } } /// <summary> ///Set background color /// </summary> void BackgroundColor(int& theRed, int& theGreen, int& theBlue) { Standard_Real R1; Standard_Real G1; Standard_Real B1; if (!myView().IsNull()) { myView()->BackgroundColor(Quantity_TOC_RGB,R1,G1,B1); } theRed = (int)R1*255; theGreen = (int)G1*255; theBlue = (int)B1*255; } /// <summary> ///Get background color Red /// </summary> int GetBGColR(void) { int aRed, aGreen, aBlue; BackgroundColor(aRed, aGreen, aBlue); return aRed; } /// <summary> ///Get background color Green /// </summary> int GetBGColG(void) { int aRed, aGreen, aBlue; BackgroundColor(aRed, aGreen, aBlue); return aGreen; } /// <summary> ///Get background color Blue /// </summary> int GetBGColB(void) { int aRed, aGreen, aBlue; BackgroundColor(aRed, aGreen, aBlue); return aBlue; } /// <summary> ///Update current viewer /// </summary> void UpdateCurrentViewer(void) { if (!myAISContext().IsNull()) { myAISContext()->UpdateCurrentViewer(); } } /// <summary> ///Front side /// </summary> void FrontView(void) { if (!myView().IsNull()) { myView()->SetProj(V3d_Yneg); } } /// <summary> ///Top side /// </summary> void TopView(void) { if (!myView().IsNull()) { myView()->SetProj(V3d_Zpos); } } /// <summary> ///Left side /// </summary> void LeftView(void) { if (!myView().IsNull()) { myView()->SetProj(V3d_Xneg); } } /// <summary> ///Back side /// </summary> void BackView(void) { if (!myView().IsNull()) { myView()->SetProj(V3d_Ypos); } } /// <summary> ///Right side /// </summary> void RightView(void) { if (!myView().IsNull()) { myView()->SetProj(V3d_Xpos); } } /// <summary> ///Bottom side /// </summary> void BottomView(void) { if (!myView().IsNull()) { myView()->SetProj(V3d_Zneg); } } /// <summary> ///Axo side /// </summary> void AxoView(void) { if (!myView().IsNull()) { myView()->SetProj(V3d_XposYnegZpos); } } /// <summary> ///Scale /// </summary> float Scale(void) { if (myView().IsNull()) { return -1; } else { return (float)myView()->Scale(); } } /// <summary> ///Zoom in all view /// </summary> void ZoomAllView(void) { if (!myView().IsNull()) { myView()->FitAll(); myView()->ZFitAll(); } } /// <summary> ///Reset view /// </summary> void Reset(void) { if (!myView().IsNull()) { myView()->Reset(); } } /// <summary> ///Set display mode of objects /// </summary> /// <param name="theMode">Set current mode</param> void SetDisplayMode(int theMode) { if (myAISContext().IsNull()) { return; } AIS_DisplayMode aCurrentMode; if (theMode == 0) { aCurrentMode=AIS_WireFrame; } else { aCurrentMode=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(); } /// <summary> ///Set color /// </summary> void SetColor(int theR, int theG, int theB) { if (myAISContext().IsNull()) { return; } Quantity_Color aCol = Quantity_Color(theR/255.,theG/255.,theB/255.,Quantity_TOC_RGB); for (; myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { myAISContext()->SetColor (myAISContext()->SelectedInteractive(), aCol, Standard_False); } myAISContext()->UpdateCurrentViewer(); } /// <summary> ///Get object color red /// </summary> int GetObjColR(void) { int aRed, aGreen, aBlue; ObjectColor(aRed, aGreen, aBlue); return aRed; } /// <summary> ///Get object color green /// </summary> int GetObjColG(void) { int aRed, aGreen, aBlue; ObjectColor(aRed, aGreen, aBlue); return aGreen; } /// <summary> ///Get object color R/G/B /// </summary> void ObjectColor(int& theRed, int& theGreen, int& theBlue) { if (myAISContext().IsNull()) { return; } theRed=255; theGreen=255; theBlue=255; Handle(AIS_InteractiveObject) aCurrent ; myAISContext()->InitSelected(); if (!myAISContext()->MoreSelected()) { return; } aCurrent = myAISContext()->SelectedInteractive(); if ( aCurrent->HasColor () ) { Quantity_Color anObjCol; myAISContext()->Color (aCurrent, anObjCol); Standard_Real r1, r2, r3; anObjCol.Values(r1, r2, r3, Quantity_TOC_RGB); theRed=(int)r1*255; theGreen=(int)r2*255; theBlue=(int)r3*255; } } /// <summary> ///Get object color blue /// </summary> int GetObjColB(void) { int aRed, aGreen, aBlue; ObjectColor(aRed, aGreen, aBlue); return aBlue; } /// <summary> ///Set background color R/G/B /// </summary> void SetBackgroundColor(int theRed, int theGreen, int theBlue) { if (!myView().IsNull()) { myView()->SetBackgroundColor(Quantity_TOC_RGB, theRed/255.,theGreen/255.,theBlue/255.); } } /// <summary> ///Erase objects /// </summary> void EraseObjects(void) { if (myAISContext().IsNull()) { return; } myAISContext()->EraseSelected (Standard_False); myAISContext()->ClearSelected (Standard_True); } /// <summary> ///Get version /// </summary> float GetOCCVersion(void) { return (float)OCC_VERSION; } /// <summary> ///set material /// </summary> 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(); } /// <summary> ///set transparency /// </summary> 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(); } /// <summary> ///Return true if object is selected /// </summary> bool IsObjectSelected(void) { if (myAISContext().IsNull()) { return false; } myAISContext()->InitSelected(); return myAISContext()->MoreSelected() != Standard_False; } /// <summary> ///Return display mode /// </summary> int DisplayMode(void) { if (myAISContext().IsNull()) { return -1; } int aMode = -1; bool OneOrMoreInShading = false; bool OneOrMoreInWireframe = false; for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected()) { if ( myAISContext()->IsDisplayed( myAISContext()->SelectedInteractive(), 1 ) ) { OneOrMoreInShading = true; } if ( myAISContext()->IsDisplayed( myAISContext()->SelectedInteractive(), 0 ) ) { OneOrMoreInWireframe = true; } } if (OneOrMoreInShading && OneOrMoreInWireframe) { aMode=10; } else if(OneOrMoreInShading) { aMode=1; } else if (OneOrMoreInWireframe) { aMode=0; } return aMode; } /// <summary> ///Create new view /// </summary> /// <param name="theWnd">System.IntPtr that contains the window handle (HWND) of the control</param> void CreateNewView(System::IntPtr theWnd) { if (myAISContext().IsNull()) { return; } myView() = myAISContext()->CurrentViewer()->CreateView(); if (myGraphicDriver().IsNull()) { myGraphicDriver() = new OpenGl_GraphicDriver (Handle(Aspect_DisplayConnection)()); } Handle(WNT_Window) aWNTWindow = new WNT_Window (reinterpret_cast<HWND> (theWnd.ToPointer())); myView()->SetWindow(aWNTWindow); Standard_Integer w=100, h=100; aWNTWindow->Size(w,h); if (!aWNTWindow->IsMapped()) { aWNTWindow->Map(); } } /// <summary> ///Set AISContext /// </summary> bool SetAISContext(OCCTProxy^ theViewer) { this->myAISContext() = theViewer->GetContext(); if (myAISContext().IsNull()) { return false; } return true; } /// <summary> ///Get AISContext /// </summary> Handle(AIS_InteractiveContext) GetContext(void) { return myAISContext(); } public: // ============================================ // Import / export functionality // ============================================ /// <summary> ///Import BRep file /// </summary> /// <param name="theFileName">Name of import file</param> bool ImportBrep(System::String^ theFileName) { return ImportBrep (toAsciiString (theFileName)); } /// <summary> ///Import BRep file /// </summary> /// <param name="theFileName">Name of import file</param> bool ImportBrep (const TCollection_AsciiString& theFileName) { TopoDS_Shape aShape; BRep_Builder aBuilder; Standard_Boolean isResult = BRepTools::Read(aShape,theFileName.ToCString(),aBuilder); if (!isResult) { return false; } myAISContext()->Display (new AIS_Shape (aShape), Standard_True); return true; } /// <summary> ///Import Step file /// </summary> /// <param name="theFileName">Name of import file</param> bool ImportStep(const TCollection_AsciiString& theFileName) { STEPControl_Reader aReader; IFSelect_ReturnStatus aStatus = aReader.ReadFile(theFileName.ToCString()); if ( aStatus == IFSelect_RetDone ) { bool isFailsonly = false; aReader.PrintCheckLoad( isFailsonly, IFSelect_ItemsByEntity ); int aNbRoot = aReader.NbRootsForTransfer(); aReader.PrintCheckTransfer( isFailsonly, IFSelect_ItemsByEntity ); for ( Standard_Integer n = 1; n <= aNbRoot; n++ ) { Standard_Boolean ok = aReader.TransferRoot( n ); int aNbShap = aReader.NbShapes(); if ( aNbShap > 0 ) { for ( int i = 1; i <= aNbShap; i++ ) { TopoDS_Shape aShape = aReader.Shape( i ); myAISContext()->Display (new AIS_Shape (aShape), Standard_False); } myAISContext()->UpdateCurrentViewer(); } } } else { return false; } return true; } /// <summary> ///Import Iges file /// </summary> /// <param name="theFileName">Name of import file</param> bool ImportIges(const TCollection_AsciiString& theFileName) { IGESControl_Reader aReader; int aStatus = aReader.ReadFile( theFileName.ToCString() ); if ( aStatus == IFSelect_RetDone ) { aReader.TransferRoots(); TopoDS_Shape aShape = aReader.OneShape(); myAISContext()->Display (new AIS_Shape (aShape), Standard_False); } else { return false; } myAISContext()->UpdateCurrentViewer(); return true; } /// <summary> ///Export BRep file /// </summary> /// <param name="theFileName">Name of export file</param> bool ExportBRep(const TCollection_AsciiString& theFileName) { myAISContext()->InitSelected(); if (!myAISContext()->MoreSelected()) { return false; } Handle(AIS_InteractiveObject) anIO = myAISContext()->SelectedInteractive(); Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast(anIO); return BRepTools::Write (anIS->Shape(), theFileName.ToCString()) != Standard_False; } /// <summary> ///Export Step file /// </summary> /// <param name="theFileName">Name of export file</param> bool ExportStep(const TCollection_AsciiString& theFileName) { STEPControl_StepModelType aType = STEPControl_AsIs; IFSelect_ReturnStatus aStatus; STEPControl_Writer aWriter; for ( myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected() ) { Handle(AIS_InteractiveObject) anIO = myAISContext()->SelectedInteractive(); Handle(AIS_Shape) anIS=Handle(AIS_Shape)::DownCast(anIO); TopoDS_Shape aShape = anIS->Shape(); aStatus = aWriter.Transfer( aShape , aType ); if ( aStatus != IFSelect_RetDone ) { return false; } } aStatus = aWriter.Write(theFileName.ToCString()); if ( aStatus != IFSelect_RetDone ) { return false; } return true; } /// <summary> ///Export Iges file /// </summary> /// <param name="theFileName">Name of export file</param> 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_InteractiveObject) anIO = myAISContext()->SelectedInteractive(); Handle(AIS_Shape) anIS=Handle(AIS_Shape)::DownCast(anIO); TopoDS_Shape aShape = anIS->Shape(); aWriter.AddShape ( aShape ); } aWriter.ComputeModel(); return aWriter.Write(theFileName.ToCString()) != Standard_False; } /// <summary> ///Export Vrml file /// </summary> /// <param name="theFileName">Name of export file</param> bool ExportVrml(const TCollection_AsciiString& theFileName) { TopoDS_Compound aRes; BRep_Builder aBuilder; aBuilder.MakeCompound( aRes ); for ( myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected() ) { Handle(AIS_InteractiveObject) anIO = myAISContext()->SelectedInteractive(); Handle(AIS_Shape) anIS=Handle(AIS_Shape)::DownCast(anIO); TopoDS_Shape aShape = anIS->Shape(); if ( aShape.IsNull() ) { return false; } aBuilder.Add( aRes, aShape ); } VrmlAPI_Writer aWriter; aWriter.Write(aRes, theFileName.ToCString()); return true; } /// <summary> ///Export Stl file /// </summary> /// <param name="theFileName">Name of export file</param> bool ExportStl(const TCollection_AsciiString& theFileName) { TopoDS_Compound aComp; BRep_Builder aBuilder; aBuilder.MakeCompound( aComp ); for ( myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected() ) { Handle(AIS_InteractiveObject) anIO = myAISContext()->SelectedInteractive(); Handle(AIS_Shape) anIS=Handle(AIS_Shape)::DownCast(anIO); TopoDS_Shape aShape = anIS->Shape(); if ( aShape.IsNull() ) { return false; } aBuilder.Add( aComp, aShape ); } StlAPI_Writer aWriter; aWriter.Write(aComp, theFileName.ToCString()); return true; } /// <summary> ///Define which Import/Export function must be called /// </summary> /// <param name="theFileName">Name of Import/Export file</param> /// <param name="theFormat">Determines format of Import/Export file</param> /// <param name="theIsImport">Determines is Import or not</param> bool TranslateModel(System::String^ theFileName, int theFormat, bool theIsImport) { bool isResult; 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; default: isResult = false; } } 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; default: isResult = false; } } return isResult; } /// <summary> ///Initialize OCCTProxy /// </summary> void InitOCCTProxy(void) { myGraphicDriver()=NULL; myViewer()=NULL; myView()=NULL; myAISContext()=NULL; } private: // fields NCollection_Haft<Handle(V3d_Viewer)> myViewer; NCollection_Haft<Handle(V3d_View)> myView; NCollection_Haft<Handle(AIS_InteractiveContext)> myAISContext; NCollection_Haft<Handle(OpenGl_GraphicDriver)> myGraphicDriver; };