Skip to content

Commit

Permalink
Backup work on carving
Browse files Browse the repository at this point in the history
  • Loading branch information
epernod committed Oct 18, 2024
1 parent 6321b6e commit 2d01fdb
Show file tree
Hide file tree
Showing 7 changed files with 396 additions and 5 deletions.
37 changes: 35 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ set(SOURCE_FILES
# Add component for carving using refinement mesh
find_package(MeshRefinement QUIET)
if (MeshRefinement_FOUND)
message("MeshRefinement plugin found - Adding it to ${PROJECT_NAME}")
message("## ${PROJECT_NAME}: MeshRefinement plugin found")

list(APPEND HEADER_FILES
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/RefineCarvingPerformer.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/CuttingPerformer.h
Expand All @@ -92,6 +93,34 @@ if (MeshRefinement_FOUND)
add_definitions(-DHAS_MESHREFINEMENT_PLUGIN)
endif()


find_package(Sofa.GUI.Qt QUIET)
if (Sofa.GUI.Qt_FOUND)
message("## ${PROJECT_NAME}: Sofa.GUI.Qt plugin found")

list(APPEND HEADER_FILES
${INFINYTOOLKIT_SRC_DIR}/MouseCarvingOperation/CarvingOperation.h
)
list(APPEND SOURCE_FILES
${INFINYTOOLKIT_SRC_DIR}/MouseCarvingOperation/CarvingOperation.cpp
${INFINYTOOLKIT_SRC_DIR}/MouseCarvingOperation/QCarvingOperation.cpp
)

set(MOC_HEADER_FILES
${INFINYTOOLKIT_SRC_DIR}/MouseCarvingOperation/QCarvingOperation.h
)

if (Qt5Core_FOUND)
qt5_wrap_cpp(MOC_FILES ${MOC_HEADER_FILES})
qt5_wrap_ui(FORM_FILES ${UI_FILES})
elseif (Qt6Core_FOUND)
qt6_wrap_cpp(MOC_FILES ${MOC_HEADER_FILES})
qt6_wrap_ui(FORM_FILES ${UI_FILES})
endif()

add_definitions(-DUSE_GUI)
endif()

set(README_FILES README.md)

# Create the plugin library.
Expand All @@ -101,7 +130,7 @@ add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES} ${README_FILE
target_compile_definitions(${PROJECT_NAME} PRIVATE "-DSOFA_BUILD_INFINYTOOLKIT")

# Link the plugin library to its dependencies (other libraries).
target_link_libraries(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME} PUBLIC
Sofa.Component.StateContainer
Sofa.Component.MechanicalLoad
Sofa.Component.Topology.Container.Dynamic
Expand All @@ -118,6 +147,10 @@ if(MeshRefinement_FOUND)
target_link_libraries(${PROJECT_NAME} MeshRefinement)
endif()

if(Sofa.GUI.Qt_FOUND)
target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.GUI.Qt)
endif()


target_include_directories(${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>")
target_include_directories(${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>")
Expand Down
4 changes: 2 additions & 2 deletions examples/Cube_AdvCarvingWithRefinement.scn
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
<BruteForceBroadPhase/>
<BVHNarrowPhase/>
<CollisionResponse response="PenalityContactForceField" />
<MinProximityIntersection name="Proximity" alarmDistance="1.0" contactDistance="0.1" />
<MinProximityIntersection name="Proximity" alarmDistance="2.0" contactDistance="0.1" />

<EulerImplicitSolver name="EulerImplicit" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver name="CG Solver" iterations="25" tolerance="1e-9" threshold="1e-9"/>

<AdvancedCarvingManager name="ACarving" active="1" refineDistance="1.0" refineCriteria="0.5" carvingDistance="0.5"
<AdvancedCarvingManager name="ACarving" active="1" refineDistance="1.5" refineCriteria="0.5" carvingDistance="0.5"
carvingWithBurning="0" carvingWithRefinement="1" drawContacts="0" process="1"/>

<Node name="carvingElement">
Expand Down
2 changes: 1 addition & 1 deletion src/InfinyToolkit/CarvingTools/AdvancedCarvingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ AdvancedCarvingManager::AdvancedCarvingManager()
, d_cuttingMode(initData(&d_cuttingMode, false, "cuttingMode", "Activate the option tetrahedral cutting."))
, d_carvingDistance( initData(&d_carvingDistance, 0.0, "carvingDistance", "Collision distance at which cavring will start. Equal to contactDistance by default."))
, d_refineDistance(initData(&d_refineDistance, 0.0, "refineDistance", "Collision distance at which cavring will start. Equal to contactDistance by default."))
, d_refineCriteria( initData(&d_refineCriteria, 0.5, "refineCriteria", "Collision distance at which cavring will start. Equal to contactDistance by default."))
, d_refineCriteria( initData(&d_refineCriteria, 0.5, "refineCriteria", "Factor to determine the minimum thresold to not devide a tetrahedron (minVolume = criteria*refVolume)."))
, d_carvingSpeed(initData(&d_carvingSpeed, 0.001, "carvingSpeed", "Collision distance at which cavring will start. Equal to contactDistance by default."))
, d_refineThreshold(initData(&d_refineThreshold, 1.0, "refineThreshold", "Collision distance at which cavring will start. Equal to contactDistance by default."))
, m_testID(initData(&m_testID, sofa::type::vector<unsigned int>(), "testID", "Scale of the terahedra (between 0 and 1; if <1.0, it produces gaps between the tetrahedra)"))
Expand Down
203 changes: 203 additions & 0 deletions src/InfinyToolkit/MouseCarvingOperation/CarvingOperation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/*****************************************************************************
* Copyright (C) - InfinyTech3D - All Rights Reserved *
* *
* Unauthorized copying of this file, via any medium is strictly prohibited *
* Proprietary and confidential. *
* *
* Written by Erik Pernod <erik.pernod@infinytech3d.com>, June 2021 *
****************************************************************************/
#include <MeshRefinement/MouseCuttingOperation/CuttingOperation.h>
#include <sofa/component/topology/container/dynamic/TetrahedronSetTopologyContainer.h>
#include <sofa/gui/common/MouseOperations.h>
#include <sofa/gui/component/performer/ComponentMouseInteraction.h>
#include <sofa/gui/common/PickHandler.h>

namespace sofa::gui::component::performer
{

CuttingPerformer::CuttingPerformer(BaseMouseInteractor* interactor)
: InteractionPerformer(interactor)
, m_tetraCuttingMgr(nullptr)
, m_topoCon(nullptr)
, m_topoGeo(nullptr)
, isInit(false)
, clickCount(0)
, m_depth(1.0)
{
m_tetraCuttingMgr = new sofa::meshrefinement::TetrahedronCuttingManager<sofa::defaulttype::Vec3Types>();
}


void CuttingPerformer::start()
{
////pickHandle->getInteraction()->mouseInteractor;
//std::cout << "CuttingPerformer::start()" << std::endl;

BodyPicked picked = this->m_interactor->getBodyPicked();
if (!picked.body) return;

if (!isInit)
{
sofa::core::objectmodel::BaseContext* base = picked.body->getContext();

m_topoCon = base->get<TetrahedronSetTopologyContainer>();
if (m_topoCon == nullptr) // possible Tetra2Triangle topology
{
base->get(m_topoCon, core::objectmodel::BaseContext::SearchUp);
if (m_topoCon == nullptr)
{
msg_warning("CuttingPerformer") << "No TetrahedronSetTopologyContainer found in target object.";
isInit = false;
return;
}
else
{
m_topoGeo = m_topoCon->getContext()->get<TetrahedronSetGeometryAlgorithms<sofa::defaulttype::Vec3Types>>();
}
}
else {
m_topoGeo = m_topoCon->getContext()->get<TetrahedronSetGeometryAlgorithms<sofa::defaulttype::Vec3Types>>();
}

m_tetraCuttingMgr->init(m_topoCon->getContext());
isInit = true;
}


if (clickCount == 0)
{
m_pos0 = picked.point;
clickCount++;
}
else if (clickCount == 1)
{
if (!m_topoGeo)
return;

m_pos1 = picked.point;

fixed_array<Vec3, 4> m_planPositions;
m_planPositions[0] = m_pos0;
m_planPositions[1] = m_pos1;

// sofa::component::collision::RayCollisionModel* rayModel = this->interactor->getMouseRayModel();
sofa::component::collision::geometry::Ray ray = this->m_interactor->getMouseRayModel()->getRay(0);
Vec3 normA = -ray.direction();
normA.normalize();
// = m_topoGeo->computeTriangleNormal(picked.indexCollisionElement);
//normA.normalize();

m_planPositions[2] = m_planPositions[1] - normA * m_depth * 0.1;
m_planPositions[3] = m_planPositions[0] - normA * m_depth * 0.1;

Vec3 m_planNormal = (m_planPositions[1] - m_planPositions[0]).cross(normA);
m_tetraCuttingMgr->createCutPlanPath(m_planPositions, m_planNormal, 1.0);

clickCount++;
}
else if (clickCount == 2)
{
m_tetraCuttingMgr->processCut(false);
}
}


void CuttingPerformer::execute()
{
BodyPicked picked = this->m_interactor->getBodyPicked();
if (!picked.body) return;

if (clickCount == 1)
{
m_pos1 = picked.point;
}

}


void CuttingPerformer::draw(const core::visual::VisualParams* vparams)
{
if (!isInit)
return;

if (clickCount > 0) {
vparams->drawTool()->drawSphere(m_pos0, float(1.0), RGBAColor::red());
}
if (clickCount > 1) {
vparams->drawTool()->drawSphere(m_pos1, float(1.0), RGBAColor::green());
m_tetraCuttingMgr->drawCutPlan(vparams);
m_tetraCuttingMgr->drawDebugCut(vparams);
}





}


sofa::helper::Creator<InteractionPerformer::InteractionPerformerFactory, CuttingPerformer > CuttingPerformerClass("CuttingPerformer", true);

} // namespace sofa::gui::component::performer



namespace sofa::gui::common
{

CuttingOperation::CuttingOperation()
: clickCount(0)
{

}

CuttingOperation::~CuttingOperation()
{

}

void CuttingOperation::start()
{
if (performer == nullptr)
{
performer = component::performer::InteractionPerformer::InteractionPerformerFactory::getInstance()->createObject("CuttingPerformer", pickHandle->getInteraction()->mouseInteractor.get());
pickHandle->getInteraction()->mouseInteractor->addInteractionPerformer(performer);

component::performer::CuttingPerformer* performerCut = dynamic_cast<component::performer::CuttingPerformer*>(performer);
if (performerCut)
performerCut->setIncisionDepth(this->getDepth());
}

if (performer) {
performer->start();
}

//if (clickCount == 0)
//{
//
//}

}

void CuttingOperation::execution()
{
//std::cout << "CuttingOperation::execution()" << std::endl;
}

void CuttingOperation::end()
{
//std::cout << "CuttingOperation::end()" << std::endl;
}

void CuttingOperation::endOperation()
{
if (performer)
{
pickHandle->getInteraction()->mouseInteractor->removeInteractionPerformer(performer);
delete performer; performer = nullptr;
clickCount = 0;
}
}


} // namespace sofa::gui::common
74 changes: 74 additions & 0 deletions src/InfinyToolkit/MouseCarvingOperation/CarvingOperation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*****************************************************************************
* Copyright (C) - InfinyTech3D - All Rights Reserved *
* *
* Unauthorized copying of this file, via any medium is strictly prohibited *
* Proprietary and confidential. *
* *
* Written by Erik Pernod <erik.pernod@infinytech3d.com>, June 2021 *
****************************************************************************/
#pragma once

#include <MeshRefinement/config.h>
#include <MeshRefinement/TetrahedronCuttingManager.h>
#include <sofa/gui/common/MouseOperations.h>
#include <sofa/gui/component/performer/InteractionPerformer.h>

using sofa::meshrefinement::TetrahedronCuttingManager;

namespace sofa::gui::component::performer
{

class SOFA_MESHREFINEMENT_API CuttingPerformer : public InteractionPerformer
{
public:
CuttingPerformer(BaseMouseInteractor* interactor);

void start();
void execute();
void draw(const core::visual::VisualParams* vparams);

void setIncisionDepth(double value) { m_depth = value; }

protected:
sofa::meshrefinement::TetrahedronCuttingManager<sofa::defaulttype::Vec3Types>* m_tetraCuttingMgr;
TetrahedronSetTopologyContainer* m_topoCon;
TetrahedronSetGeometryAlgorithms<sofa::defaulttype::Vec3Types>::SPtr m_topoGeo;

Vec3 m_pos0;
Vec3 m_pos1;

double m_depth;

bool isInit;
int clickCount;
};

} // namespace sofa::gui::component::performer


namespace sofa::gui::common
{

class SOFA_MESHREFINEMENT_API CuttingOperation : public Operation
{
public:
CuttingOperation();
~CuttingOperation();

void start() override;
void execution() override;
void end() override;
void endOperation() override;

virtual double getDepth() const { return incisionDepth; }

static std::string getDescription() { return "3D mesh incision using the Mouse"; }

protected:
double incisionDepth;
int clickCount;
};



} // namespace sofa::gui::common
Loading

0 comments on commit 2d01fdb

Please sign in to comment.