For all issues regarding the Forums use, please, refer to the Forum Rules.

Our Solutions

Need professional assistance?
Consider our:

Support Offerings

 

Need to speed up your development?
Have a look at our:

Samples & Tools

 

Need some functionality extending standard OCCT capabilities?
Check out our:

Adv. Components

OpenCascade cannot work properly with DirectX

chengmengli's picture
Forums: 

I want to build a project which use Opencascade to do modeling operations and generate meshes, and use DirectX for display meshes. However, immediately after calling IDirectD3D9::CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, this->m_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice), the Opencascade library does not function correctly. I test with BrepBuilderAPI_MakeWire, I make the wire as following:
BRepBuilderAPI_MakeWire occWire;
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(10, 0, 0)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(10, 0, 0), gp_Pnt(10, 10, 0)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(10, 10, 0), gp_Pnt(0, 10, 0)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(0, 10, 0), gp_Pnt(0, 0, 0)));
and then use BRepTools_WireExplorer to explorer the edge, and print the vertex coordinates, and get the following result:
occWire:
(-1.#IND -1.#IND -1.#IND), (-1.#IND -1.#IND -1.#IND)
(-1.#IND -1.#IND -1.#IND), (-1.#IND -1.#IND -1.#IND)
(-1.#IND -1.#IND -1.#IND), (-1.#IND -1.#IND -1.#IND)
(-1.#IND -1.#IND -1.#IND), (-1.#IND -1.#IND -1.#IND)
However, before IDirect3D9::CreateDevice() is called, the above functions works correctly. Somehow, directx is conflit with OpenCascade. Does anyone meet the sistuation before? Or is there any important preprocess flags that needed to set?

I put the problem code here:
void CTestOccView::OnInitialUpdate()
{
CView::OnInitialUpdate();

// TODO: 在此添加专用代码和/或调用基类
D3DDISPLAYMODE displayMode;
IDirect3D9 * g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));

d3dpp.BackBufferWidth = 1024;
d3dpp.BackBufferHeight = 768;
d3dpp.Windowed = TRUE;
d3dpp.BackBufferWidth = 800;
d3dpp.BackBufferHeight = 600;

d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;

LPDIRECT3DDEVICE9 g_pD3DDevice;

testHalfSpaceSolid2(); //this step works correctly

if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, this->m_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,
&g_pD3DDevice)))
{
MessageBox(_T("Failed!\n"));
}

testHalfSpaceSolid2(); //after calling CreateDevice, this step does not work correctly

void printEdge(const TopoDS_Edge & occEdge)
{
TopExp_Explorer vertexExp;
vertexExp.Init(occEdge, TopAbs_VERTEX);
gp_Pnt pt0 = BRep_Tool::Pnt(TopoDS::Vertex(vertexExp.Current()));
vertexExp.Next();
gp_Pnt pt1 = BRep_Tool::Pnt(TopoDS::Vertex(vertexExp.Current()));
TRACE("(%g %g %g), ", pt0.X(), pt0.Y(), pt0.Z());

TRACE("(%g %g %g) \n", pt1.X(), pt1.Y(), pt1.Z());
}

void printWire(const TopoDS_Wire & occWire)
{
for(BRepTools_WireExplorer edgeExp(occWire); edgeExp.More(); edgeExp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(edgeExp.Current());
TopExp_Explorer vertexExp;
vertexExp.Init(edge, TopAbs_VERTEX);
gp_Pnt pt0 = BRep_Tool::Pnt(TopoDS::Vertex(vertexExp.Current()));
vertexExp.Next();
gp_Pnt pt1 = BRep_Tool::Pnt(TopoDS::Vertex(vertexExp.Current()));
TRACE("(%g %g %g), ", pt0.X(), pt0.Y(), pt0.Z());

TRACE("(%g %g %g) \n", pt1.X(), pt1.Y(), pt1.Z());
}
}

void printShape(const TopoDS_Shape & tShape)
{
BRepMesh::Mesh(tShape,0.001f);
TopExp_Explorer exp;
int faceCount = 0;
for(exp.Init(tShape, TopAbs_FACE); exp.More(); exp.Next())
{
TopoDS_Face face = TopoDS::Face(exp.Current());
GProp_GProps areaProp;
BRepGProp::SurfaceProperties(face, areaProp, 0.001);
TRACE("Face area: %g\n", areaProp.Mass());

TopExp_Explorer wireExp;
for (wireExp.Init(face, TopAbs_WIRE); wireExp.More(); wireExp.Next())
{
TopoDS_Wire wire = TopoDS::Wire(wireExp.Current());
TRACE("[\n");
for(BRepTools_WireExplorer edgeExp(wire, face); edgeExp.More(); edgeExp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(edgeExp.Current());
TopExp_Explorer vertexExp;
vertexExp.Init(edge, TopAbs_VERTEX);
gp_Pnt pt0 = BRep_Tool::Pnt(TopoDS::Vertex(vertexExp.Current()));
vertexExp.Next();
gp_Pnt pt1 = BRep_Tool::Pnt(TopoDS::Vertex(vertexExp.Current()));
//if (edge.Orientation() == TopAbs_REVERSED)
//{
// gp_Pnt tmpPt = pt1;
// pt1 = pt0;
// pt0 = tmpPt;
//}
TRACE("(%g %g %g), ", pt0.X(), pt0.Y(), pt0.Z());

TRACE("(%g %g %g) \n", pt1.X(), pt1.Y(), pt1.Z());
}
TRACE("]\n");
}
TRACE("--\n");
faceCount++;

//TopLoc_Location loc;
//Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face, loc);
//if (!tri.IsNull())
//{
// const TColgp_Array1OfPnt & nodes = tri->Nodes();
// int len = nodes.Length();
// for(int i = nodes.Lower(); i // {
// gp_Pnt pt = nodes.Value(i);
// printf("%g %g %g\n", pt.Coord(1), pt.Coord(2), pt.Coord(3));
// }

// printf("%d----\n", len);
// faceCount++;
//}
}

TRACE("FaceCount: %d \n", faceCount);
}

void testHalfSpaceSolid2()
{
gp_Pln occPlane(gp_Pnt(0, 0, 5950), gp_Dir(0, 0, 1));
TopoDS_Face occF = BRepBuilderAPI_MakeFace(occPlane);
gp_Pnt occPnt = occPlane.Location();
occPnt.Translate(occPlane.Axis().Direction());
TopoDS_Shape occHalfSpace = BRepPrimAPI_MakeHalfSpace(occF, occPnt).Solid();

printEdge(BRepBuilderAPI_MakeEdge(gp_Pnt(0, -204, -4150), gp_Pnt(9708, -204, -4150)));

BRepBuilderAPI_MakeWire occWire;
/*occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(0, -204, -4150), gp_Pnt(9708, -204, -4150)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(9708, -204, -4150), gp_Pnt(9708, 204, -4150)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(9708, 204, -4150), gp_Pnt(0, 204, -4150)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(0, 204, -4150), gp_Pnt(0, -204, -4150)));*/

occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(10, 0, 0)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(10, 0, 0), gp_Pnt(10, 10, 0)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(10, 10, 0), gp_Pnt(0, 10, 0)));
occWire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(0, 10, 0), gp_Pnt(0, 0, 0)));

TRACE("occWire:\n");
printWire(occWire.Wire());

TopoDS_Face occF1 = BRepBuilderAPI_MakeFace(occWire.Wire());
TopoDS_Shape occS = BRepPrimAPI_MakePrism(occWire, gp_Vec(0, 0, 20000));

TRACE("occS:\n");
printShape(occS);

TopoDS_Shape occCutS = BRepAlgoAPI_Cut(occS, occHalfSpace);
TRACE("occCutS:\n");
printShape(occCutS);
}

Shockwave's picture

I think that the right way to make OpenCascade working with DirectX is to make a new TKDirectX.dll implementing the same interface as TKOpenGl.dll writing the code for rendering with directX only in this dll, as it will be possible to change the rendering mode from OpenGl to DirectX without changing the application code but only using a different dll for rendering.