1 #include "BridgeFBO.hxx"
3 // include required OCCT headers
4 #include <Standard_Version.hxx>
5 #include <Message_ProgressIndicator.hxx>
7 #include <Aspect_DisplayConnection.hxx>
8 #include <WNT_Window.hxx>
9 #include <Graphic3d_CView.hxx>
10 #include <Graphic3d_Camera.hxx>
11 #include <Graphic3d_TextureParams.hxx>
12 #include <OpenGl_GraphicDriver.hxx>
13 #include <OpenGl_CView.hxx>
15 #include <V3d_Viewer.hxx>
16 #include <V3d_View.hxx>
17 #include <Visual3d_View.hxx>
18 #include <AIS_InteractiveContext.hxx>
19 #include <AIS_Shape.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopoDS_Compound.hxx>
24 #include <BRep_Builder.hxx>
25 #include <BRepTools.hxx>
27 #include <IGESControl_Reader.hxx>
28 #include <IGESControl_Controller.hxx>
29 #include <IGESControl_Writer.hxx>
30 #include <IFSelect_ReturnStatus.hxx>
31 #include <Interface_Static.hxx>
33 #include <STEPControl_Reader.hxx>
34 #include <STEPControl_Writer.hxx>
36 #include <StlAPI_Writer.hxx>
38 #include <VrmlAPI_Writer.hxx>
39 //wrapper of pure C++ classes to ref classes
40 #include <NCollection_Haft.h>
42 // list of required OCCT libraries
43 #pragma comment(lib, "TKernel.lib")
44 #pragma comment(lib, "TKMath.lib")
45 #pragma comment(lib, "TKBRep.lib")
46 #pragma comment(lib, "TKXSBase.lib")
47 #pragma comment(lib, "TKService.lib")
48 #pragma comment(lib, "TKV3d.lib")
49 #pragma comment(lib, "TKOpenGl.lib")
50 #pragma comment(lib, "TKIGES.lib")
51 #pragma comment(lib, "TKSTEP.lib")
52 #pragma comment(lib, "TKStl.lib")
53 #pragma comment(lib, "TKVrml.lib")
56 /// Proxy class encapsulating calls to OCCT C++ classes within
57 /// C++/CLI class visible from .Net (CSharp)
59 public ref class OCCTProxyD3D
63 OCCTProxyD3D() : myBridgeFBO (NULL)
68 // ============================================
69 // Viewer functionality
70 // ============================================
73 ///Initialize a viewer
75 /// <param name="theWnd">System.IntPtr that contains the window handle (HWND) of the control</param>
76 bool InitViewer (System::IntPtr theWnd)
78 myGraphicDriver() = new OpenGl_GraphicDriver (Handle(Aspect_DisplayConnection)());
79 //myGraphicDriver()->ChangeOptions().contextDebug = true;
81 TCollection_ExtendedString a3DName ("Visu3D");
82 myViewer() = new V3d_Viewer (myGraphicDriver(), a3DName.ToExtString(), "", 1000.0,
83 V3d_XposYnegZpos, Quantity_NOC_GRAY30,
84 V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT,
85 Standard_True, Standard_False);
87 myViewer()->SetDefaultLights();
88 myViewer()->SetLightOn();
89 myView() = myViewer()->CreateView();
90 Handle(WNT_Window) aWNTWindow = new WNT_Window (reinterpret_cast<HWND> (theWnd.ToPointer()));
91 myView()->SetWindow(aWNTWindow);
92 if (!aWNTWindow->IsMapped())
96 myAISContext() = new AIS_InteractiveContext (myViewer());
97 myAISContext()->UpdateCurrentViewer();
98 myView()->MustBeResized();
102 /// <summary> Initializes OCCT viewer for OpenGL-Direct3D interoperability. </summary>
103 bool InitViewer (System::IntPtr theHWND,
104 System::IntPtr theD3DDevice)
106 if (!InitViewer (theHWND))
111 Graphic3d_CView* aCView = reinterpret_cast<Graphic3d_CView*> (myView()->View()->CView());
112 OpenGl_CView* aCViewGl = reinterpret_cast<OpenGl_CView*> (aCView->ptrView);
113 Handle(OpenGl_Context) aGlContext = aCViewGl->WS->GetGlContext();
114 if (aGlContext.IsNull())
118 if (!aGlContext->IsCurrent())
120 aGlContext->MakeCurrent();
123 myBridgeFBO = new BridgeFBO();
124 if (!myBridgeFBO->Init (aGlContext, theD3DDevice.ToPointer()))
129 aCView->ptrFBO = myBridgeFBO;
133 /// <summary> Resizes custom FBO for Direct3D output. </summary>
134 bool ResizeBridgeFBO (int theWinSizeX,
136 System::IntPtr theColorSurf,
137 System::IntPtr theColorSurfShare)
139 if (myBridgeFBO == NULL)
144 OpenGl_CView* aCView = reinterpret_cast<OpenGl_CView*> (reinterpret_cast<Graphic3d_CView*> (myView()->View()->CView())->ptrView);
145 Handle(OpenGl_Context) aGlContext = aCView->WS->GetGlContext();
146 if (aGlContext.IsNull()
147 || !aGlContext->MakeCurrent())
152 myBridgeFBO->Resize (aGlContext, theWinSizeX, theWinSizeY);
153 if (!myBridgeFBO->RegisterD3DColorBuffer (aGlContext, theColorSurf.ToPointer(), theColorSurfShare.ToPointer()))
158 myView()->Camera()->SetAspect (Standard_Real (theWinSizeX) / Standard_Real (theWinSizeY));
163 /// Make dump of current view to file
165 /// <param name="theFileName">Name of dump file</param>
166 bool Dump (const char* theFileName)
168 if (myView().IsNull())
173 return myView()->Dump (theFileName) != Standard_False;
181 if (!myView().IsNull())
190 void UpdateView(void)
192 if (!myView().IsNull())
194 myView()->MustBeResized();
199 ///Set computed mode in false
201 void SetDegenerateModeOn()
203 if (!myView().IsNull())
205 myView()->SetComputedMode (Standard_False);
210 ///Set computed mode in true
212 void SetDegenerateModeOff()
214 if (!myView().IsNull())
216 myView()->SetComputedMode (Standard_True);
223 void WindowFitAll (int theXmin, int theYmin,
224 int theXmax, int theYmax)
226 if (!myView().IsNull())
228 myView()->WindowFitAll (theXmin, theYmin, theXmax, theYmax);
233 ///Current place of window
235 /// <param name="theZoomFactor">Current zoom</param>
236 void Place (int theX, int theY, float theZoomFactor)
238 Quantity_Factor aZoomFactor = theZoomFactor;
239 if (!myView().IsNull())
241 myView()->Place (theX, theY, aZoomFactor);
248 void Zoom (int theX1, int theY1, int theX2, int theY2)
250 if (!myView().IsNull())
252 myView()->Zoom (theX1, theY1, theX2, theY2);
259 void Pan (int theX, int theY)
261 if (!myView().IsNull())
263 myView()->Pan (theX, theY);
270 void Rotation (int theX, int theY)
272 if (!myView().IsNull())
274 myView()->Rotation (theX, theY);
281 void StartRotation (int theX, int theY)
283 if (!myView().IsNull())
285 myView()->StartRotation (theX, theY);
290 ///Select by rectangle
292 void Select (int theX1, int theY1, int theX2, int theY2)
294 if (!myAISContext().IsNull())
296 myAISContext()->Select (theX1, theY1, theX2, theY2, myView());
305 if (!myAISContext().IsNull())
307 myAISContext()->Select();
314 void MoveTo (int theX, int theY)
316 if (!myAISContext().IsNull() && !myView().IsNull())
318 myAISContext()->MoveTo (theX, theY, myView());
323 ///Select by rectangle with pressed "Shift" key
325 void ShiftSelect (int theX1, int theY1, int theX2, int theY2)
327 if (!myAISContext().IsNull() && !myView().IsNull())
329 myAISContext()->ShiftSelect (theX1, theY1, theX2, theY2, myView());
334 ///Select by "Shift" key
338 if (!myAISContext().IsNull())
340 myAISContext()->ShiftSelect();
345 ///Set background color
347 void BackgroundColor (int& theRed, int& theGreen, int& theBlue)
349 if (!myView().IsNull())
351 Quantity_Color aColor = myView()->BackgroundColor();
352 theRed = (int )aColor.Red() * 255;
353 theGreen = (int )aColor.Green() * 255;
354 theBlue = (int )aColor.Blue() * 255;
359 ///Get background color Red
364 BackgroundColor (anRgb[0], anRgb[1], anRgb[2]);
369 ///Get background color Green
374 BackgroundColor (anRgb[0], anRgb[1], anRgb[2]);
379 ///Get background color Blue
384 BackgroundColor (anRgb[0], anRgb[1], anRgb[2]);
389 ///Update current viewer
391 void UpdateCurrentViewer()
393 if (!myAISContext().IsNull())
395 myAISContext()->UpdateCurrentViewer();
404 if (!myView().IsNull())
406 myView()->SetProj (V3d_Xpos);
415 if (!myView().IsNull())
417 myView()->SetProj (V3d_Zpos);
426 if (!myView().IsNull())
428 myView()->SetProj (V3d_Ypos);
437 if (!myView().IsNull())
439 myView()->SetProj (V3d_Xneg);
448 if (!myView().IsNull())
450 myView()->SetProj (V3d_Yneg);
459 if (!myView().IsNull())
461 myView()->SetProj (V3d_Zneg);
470 if (!myView().IsNull())
472 myView()->SetProj (V3d_XposYnegZpos);
481 return myView().IsNull()
483 : float(myView()->Scale());
491 if (!myView().IsNull())
503 if (!myView().IsNull())
510 ///Set display mode of objects
512 /// <param name="theMode">Set current mode</param>
513 void SetDisplayMode (int theMode)
515 if (myAISContext().IsNull())
520 AIS_DisplayMode aCurrentMode = theMode == 0
523 if (myAISContext()->NbCurrents() == 0
524 || myAISContext()->NbSelected() == 0)
526 myAISContext()->SetDisplayMode (aCurrentMode);
530 for (myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
532 myAISContext()->SetDisplayMode (myAISContext()->Current(), theMode, Standard_False);
535 myAISContext()->UpdateCurrentViewer();
541 void SetColor (int theR, int theG, int theB)
543 if (myAISContext().IsNull())
548 Quantity_Color aCol (theR / 255.0, theG / 255.0, theB / 255.0, Quantity_TOC_RGB);
549 for (; myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
551 myAISContext()->SetColor (myAISContext()->Current(), aCol.Name());
556 ///Get object color red
561 ObjectColor (anRgb[0], anRgb[1], anRgb[2]);
566 ///Get object color green
571 ObjectColor (anRgb[0], anRgb[1], anRgb[2]);
576 ///Get object color blue
581 ObjectColor (anRgb[0], anRgb[1], anRgb[2]);
586 ///Get object color R/G/B
588 void ObjectColor (int& theRed, int& theGreen, int& theBlue)
590 if (myAISContext().IsNull())
598 myAISContext()->InitCurrent();
599 if (!myAISContext()->MoreCurrent())
604 Handle(AIS_InteractiveObject) aCurrent = myAISContext()->Current();
605 if (aCurrent->HasColor())
607 Quantity_Color anObjCol = myAISContext()->Color (myAISContext()->Current());
608 theRed = int(anObjCol.Red() * 255.0);
609 theGreen = int(anObjCol.Green() * 255.0);
610 theBlue = int(anObjCol.Blue() * 255.0);
615 ///Set background color R/G/B
617 void SetBackgroundColor (int theRed, int theGreen, int theBlue)
619 if (!myView().IsNull())
621 myView()->SetBackgroundColor (Quantity_TOC_RGB, theRed / 255.0, theGreen / 255.0, theBlue / 255.0);
630 if (myAISContext().IsNull())
634 for(myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
636 myAISContext()->Erase (myAISContext()->Current(), Standard_True);
638 myAISContext()->ClearCurrents();
644 float GetOCCVersion()
646 return (float )OCC_VERSION;
652 void SetMaterial (int theMaterial)
654 if (myAISContext().IsNull())
658 for (myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
660 myAISContext()->SetMaterial (myAISContext()->Current(), (Graphic3d_NameOfMaterial )theMaterial);
662 myAISContext()->UpdateCurrentViewer();
668 void SetTransparency (int theTrans)
670 if (myAISContext().IsNull())
674 for (myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextSelected())
676 myAISContext()->SetTransparency (myAISContext()->Current(), ((Standard_Real )theTrans) / 10.0);
681 ///Return true if object is selected
683 bool IsObjectSelected()
685 if (myAISContext().IsNull())
689 myAISContext()->InitCurrent();
690 return myAISContext()->MoreCurrent() != Standard_False;
694 ///Return display mode
698 if (myAISContext().IsNull())
703 bool isOneOrMoreInShading = false;
704 bool isOneOrMoreInWireframe = false;
705 for (myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
707 if (myAISContext()->IsDisplayed (myAISContext()->Current(), AIS_Shaded))
709 isOneOrMoreInShading = true;
711 if (myAISContext()->IsDisplayed (myAISContext()->Current(), AIS_WireFrame))
713 isOneOrMoreInWireframe = true;
716 if (isOneOrMoreInShading
717 && isOneOrMoreInWireframe)
721 else if (isOneOrMoreInShading)
725 else if (isOneOrMoreInWireframe)
735 /// <param name="theWnd">System.IntPtr that contains the window handle (HWND) of the control</param>
736 void CreateNewView (System::IntPtr theWnd)
738 if (myAISContext().IsNull())
743 myView() = myAISContext()->CurrentViewer()->CreateView();
744 if (myGraphicDriver().IsNull())
746 myGraphicDriver() = new OpenGl_GraphicDriver (Handle(Aspect_DisplayConnection)());
747 //myGraphicDriver()->ChangeOptions().contextDebug = true;
749 Handle(WNT_Window) aWNTWindow = new WNT_Window (reinterpret_cast<HWND> (theWnd.ToPointer()));
750 myView()->SetWindow (aWNTWindow);
751 Standard_Integer aWidth = 100, aHeight = 100;
752 aWNTWindow->Size (aWidth, aHeight);
753 if (!aWNTWindow->IsMapped())
762 bool SetAISContext (OCCTProxyD3D^ theViewer)
764 this->myAISContext() = theViewer->GetContext();
765 if (myAISContext().IsNull())
775 Handle_AIS_InteractiveContext GetContext()
777 return myAISContext();
781 // ============================================
782 // Import / export functionality
783 // ============================================
788 /// <param name="theFileName">Name of import file</param>
789 bool ImportBrep (System::String^ theFileName)
791 bool isResult = false;
792 int aLength = theFileName->Length;
793 char* aFilename = new char[aLength + 1];
794 for(int i = 0; i < aLength; ++i)
796 aFilename[i] = (char )theFileName->ToCharArray()[i];
798 aFilename[aLength] = '\0';
799 isResult = ImportBrep (aFilename);
807 /// <param name="theFileName">Name of import file</param>
808 bool ImportBrep (char* theFileName)
811 BRep_Builder aBuilder;
812 if (!BRepTools::Read (aShape, theFileName, aBuilder))
816 if (myAISContext()->HasOpenedContext())
818 myAISContext()->CloseLocalContext();
820 Handle(AIS_Shape) aPrs = new AIS_Shape (aShape);
821 myAISContext()->SetMaterial (aPrs, Graphic3d_NOM_GOLD);
822 myAISContext()->SetDisplayMode(aPrs, AIS_Shaded, Standard_False);
823 myAISContext()->Display (aPrs);
830 /// <param name="theFileName">Name of import file</param>
831 bool ImportStep (char* theFileName)
833 STEPControl_Reader aReader;
834 if (aReader.ReadFile (theFileName) != IFSelect_RetDone)
839 bool isFailsonly = false;
840 aReader.PrintCheckLoad( isFailsonly, IFSelect_ItemsByEntity );
842 int aNbRoot = aReader.NbRootsForTransfer();
843 aReader.PrintCheckTransfer (isFailsonly, IFSelect_ItemsByEntity);
844 for (Standard_Integer aRootIter = 1; aRootIter <= aNbRoot; ++aRootIter)
846 aReader.TransferRoot (aRootIter);
847 int aNbShap = aReader.NbShapes();
850 for (int aShapeIter = 1; aShapeIter <= aNbShap; ++aShapeIter)
852 myAISContext()->Display (new AIS_Shape (aReader.Shape (aShapeIter)), Standard_True);
862 /// <param name="theFileName">Name of import file</param>
863 bool ImportIges (char* theFileName)
865 IGESControl_Reader aReader;
866 if (aReader.ReadFile (theFileName) != IFSelect_RetDone)
871 aReader.TransferRoots();
872 TopoDS_Shape aShape = aReader.OneShape();
873 myAISContext()->Display (new AIS_Shape (aShape), Standard_False);
874 myAISContext()->UpdateCurrentViewer();
881 /// <param name="theFileName">Name of export file</param>
882 bool ExportBRep (char* theFileName)
884 myAISContext()->InitCurrent();
885 if (!myAISContext()->MoreCurrent())
890 Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->Current());
891 return !anIS.IsNull()
892 && BRepTools::Write (anIS->Shape(), theFileName);
898 /// <param name="theFileName">Name of export file</param>
899 bool ExportStep (char* theFileName)
901 STEPControl_StepModelType aType = STEPControl_AsIs;
902 STEPControl_Writer aWriter;
903 for (myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
905 Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->Current());
911 TopoDS_Shape aShape = anIS->Shape();
912 if (aWriter.Transfer (aShape, aType) != IFSelect_RetDone)
917 return aWriter.Write (theFileName) == IFSelect_RetDone;
923 /// <param name="theFileName">Name of export file</param>
924 bool ExportIges (char* theFileName)
926 IGESControl_Controller::Init();
927 IGESControl_Writer aWriter (Interface_Static::CVal ("XSTEP.iges.unit"),
928 Interface_Static::IVal ("XSTEP.iges.writebrep.mode"));
929 for (myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
931 Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->Current());
937 aWriter.AddShape (anIS->Shape());
940 aWriter.ComputeModel();
941 return aWriter.Write (theFileName) != Standard_False;
947 /// <param name="theFileName">Name of export file</param>
948 bool ExportVrml (char* theFileName)
950 TopoDS_Compound aRes;
951 BRep_Builder aBuilder;
952 aBuilder.MakeCompound (aRes);
953 for (myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
955 Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->Current());
960 aBuilder.Add (aRes, anIS->Shape());
963 VrmlAPI_Writer aWriter;
964 aWriter.Write (aRes, theFileName);
971 /// <param name="theFileName">Name of export file</param>
972 bool ExportStl (char* theFileName)
974 TopoDS_Compound aComp;
975 BRep_Builder aBuilder;
976 aBuilder.MakeCompound (aComp);
977 for (myAISContext()->InitCurrent(); myAISContext()->MoreCurrent(); myAISContext()->NextCurrent())
979 Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->Current());
984 aBuilder.Add (aComp, anIS->Shape());
987 StlAPI_Writer aWriter;
988 aWriter.Write (aComp, theFileName);
993 ///Define which Import/Export function must be called
995 /// <param name="theFileName">Name of Import/Export file</param>
996 /// <param name="theFormat">Determines format of Import/Export file</param>
997 /// <param name="theIsImport">Determines is Import or not</param>
998 bool TranslateModel (System::String^ theFileName, int theFormat, bool theIsImport)
1000 bool isResult = false;
1001 int aLength = theFileName->Length;
1002 char* aFilename = new char[aLength + 1];
1003 for (int aCharIter = 0; aCharIter < aLength; ++aCharIter)
1005 aFilename[aCharIter] = (char)theFileName->ToCharArray()[aCharIter];
1007 aFilename[aLength] = '\0';
1013 case 0: isResult = ImportBrep (aFilename); break;
1014 case 1: isResult = ImportStep (aFilename); break;
1015 case 2: isResult = ImportIges (aFilename); break;
1022 case 0: isResult = ExportBRep (aFilename); break;
1023 case 1: isResult = ExportStep (aFilename); break;
1024 case 2: isResult = ExportIges (aFilename); break;
1025 case 3: isResult = ExportVrml (aFilename); break;
1026 case 4: isResult = ExportStl (aFilename); break;
1027 case 5: isResult = Dump (aFilename); break;
1035 ///Initialize OCCTProxyD3D
1037 void InitOCCTProxy()
1039 myGraphicDriver().Nullify();
1040 myViewer().Nullify();
1042 myAISContext().Nullify();
1047 NCollection_Haft<Handle_V3d_Viewer> myViewer;
1048 NCollection_Haft<Handle_V3d_View> myView;
1049 NCollection_Haft<Handle_AIS_InteractiveContext> myAISContext;
1050 NCollection_Haft<Handle_OpenGl_GraphicDriver> myGraphicDriver;
1051 BridgeFBO* myBridgeFBO; //!< Provides output to Direct3D buffers