BaseMesh* BoolOp::Diff (BaseMesh* mesh1, BaseMesh* mesh2) { BaseMesh* result = NULL; if (mesh1 != NULL) { if (mesh2 == NULL || !(mesh1->AABB().Intersects(mesh2->AABB()))) result = mesh1->Clone(); else{ result = ComputeBoolean(mesh1, mesh2,eDiff); if (result && result->PrimitiveCount() ==0 ) { delete result; result = NULL; } } } if (result != NULL) { result->GenID(); // result->GenSurface(); // result->GenAABB(true); } return result ; }
BaseMesh* BSPBoolOp::ComputeBoolean(PlaneMesh* mesh1, PlaneMesh* mesh2, BOOL_OP op) { BSPTree::SET_OP BSPOp; switch (op) { case eUnion: BSPOp = BSPTree::OP_UNION; break; case eIntersect: BSPOp = BSPTree::OP_INTERSECT; break; case eDiff: BSPOp = BSPTree::OP_DIFFERENCE; break; default : break; } Box3 bbox(mesh1->AABB()); bbox.IncludeBox(mesh2->AABB()); BSPTree* pTree1 = mesh1->ToBSPTree(); pTree1->FormSubHyperPlane(bbox); pTree1->OutputDebugInfo("D:\\x1.txt"); BSPTree* pTree2 = mesh2->ToBSPTree(); if (BSPOp == BSPTree::OP_DIFFERENCE) { pTree2->Negate(); BSPOp = BSPTree::OP_INTERSECT; } pTree2->FormSubHyperPlane(bbox); pTree2->OutputDebugInfo("D:\\y1.txt"); BSPTree* pResultTree = pTree1->Merge(pTree2, BSPOp); pResultTree->OutputDebugInfo("D:\\z1.txt"); delete pTree2; delete pTree1; PlaneMesh* pPlaneMesh1 = new PlaneMesh(pResultTree); //PlaneMesh* pPlaneMesh1 = new PlaneMesh(pTree1); //delete pTree1; BaseMesh* pMesh = pPlaneMesh1->ToBaseMesh(); if (pMesh && pMesh->PrimitiveCount() ==0 ) { delete pMesh; pMesh = NULL; } delete pPlaneMesh1; return pMesh; }
BaseMesh* BoolOp::Union ( BaseMesh* mesh1, BaseMesh* mesh2) { tbb::tick_count t0 = tbb::tick_count::now(); if (mesh1 == NULL && mesh2 == NULL) return NULL; if ( mesh1 == NULL) return mesh2->Clone(); if (mesh2 == NULL) return mesh1->Clone(); BaseMesh* result = NULL; if (mesh1->AABB().Intersects(mesh2->AABB())) { result = ComputeBoolean(mesh1, mesh2, eUnion); if (result && result->PrimitiveCount() ==0 ) { delete result; result = NULL; } } else { result = mesh1->Clone(); for (int i = 0; i < mesh2->PrimitiveCount(); i++) { const TriInfo& info= mesh2->TriangleInfo(i); result->Add(mesh2->Vertex(info.VertexId[0]) , mesh2->Vertex(info.VertexId[1]), mesh2->Vertex(info.VertexId[2])); } } if (result != NULL) { result->GenID(); // result->GenSurface(); // result->GenAABB(true); } /* tbb::tick_count t1 = tbb::tick_count::now(); WCHAR buffer [100]; ::swprintf_s(buffer, 100, L"Time %f mec", (t1-t0).seconds()); ::MessageBox(NULL, buffer, L"Warning", MB_OK); */ return result ; }
BaseMesh* BoolOp::Intersect (BaseMesh* mesh1, BaseMesh* mesh2) { BaseMesh* result = NULL; if (mesh1 != NULL && mesh2 != NULL && (mesh1->AABB().Intersects(mesh2->AABB()))) { result = ComputeBoolean(mesh1, mesh2, eIntersect); if (result && result->PrimitiveCount() ==0 ) { delete result; result = NULL; } } if (result != NULL) { result->GenID(); // result->GenSurface(); // result->GenAABB(true); } return result ; }
BaseMesh* BSPBoolOp::ComputeBoolean(FixedPlaneMesh* mesh1, FixedPlaneMesh* mesh2, BOOL_OP op) { GSOutputTimeLog(L"start: "); FixedBSPTree::SET_OP BSPOp; switch (op) { case eUnion: BSPOp = FixedBSPTree::OP_UNION; break; case eIntersect: BSPOp = FixedBSPTree::OP_INTERSECT; break; case eDiff: BSPOp = FixedBSPTree::OP_DIFFERENCE; break; default : break; } Box3 bbox(-1.5, -1.5, -1.5, 1.5, 1.5, 1.5); FixedBSPTree* pTree1 = mesh1->ToBSPTree(); GSOutputTimeLog(L"tree1, build: "); pTree1->FormSubHyperPlane(bbox); //pTree1->OutputDebugInfo("D:\\x.txt"); GSOutputTimeLog(L"tree1, sp: "); FixedBSPTree* pTree2 = mesh2->ToBSPTree(); GSOutputTimeLog(L"tree2, build: "); if (BSPOp == FixedBSPTree::OP_DIFFERENCE) { pTree2->Negate(); BSPOp = FixedBSPTree::OP_INTERSECT; } pTree2->FormSubHyperPlane(bbox); GSOutputTimeLog(L"tree2, sp: "); //pTree2->OutputDebugInfo("D:\\y.txt"); FixedBSPTree* pResultTree = pTree1->Merge(pTree2, BSPOp); GSOutputTimeLog(L"merged: "); //pResultTree->OutputDebugInfo("D:\\z.txt"); delete pTree2; delete pTree1; //FixedPlaneMesh* pPlaneMesh1 = new FixedPlaneMesh(pTree1, mesh1->Color());//debug2 // delete pTree1;//debug2 FixedPlaneMesh* pPlaneMesh1 = new FixedPlaneMesh(pResultTree, mesh1->Color()); delete pResultTree; GSOutputTimeLog(L"toPlaneMesh: "); pPlaneMesh1->SetAABB(mesh1->AABB()); BaseMesh* pMesh = pPlaneMesh1->ToBaseMesh(); GSOutputTimeLog(L"toBaseMesh: "); pMesh->DenormalizeCoord(); pMesh->GenAABB(true); //BaseMesh* pMesh = mesh1->ToBaseMesh();//debug1 if (pMesh && pMesh->PrimitiveCount() ==0 ) { delete pMesh; pMesh = NULL; } delete pPlaneMesh1; return pMesh; return nullptr; }