Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ set(HEADER_FILES

## Carving tools sections
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/AdvancedCarvingManager.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/BaseCarvingPerformer.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/SurfaceCarvingPerformer.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/BurningPerformer.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/BaseCarvingPerformer.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/SimpleCarvingPerformer.h

${INFINYTOOLKIT_SRC_DIR}/CarvingTools/BurningPerformer.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/SurfaceCarvingPerformer.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/HapticCarvingManager.h

${INFINYTOOLKIT_SRC_DIR}/BruteForceFeedback.h
)

Expand All @@ -57,11 +57,11 @@ set(SOURCE_FILES
## Carving tools sections
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/AdvancedCarvingManager.cpp
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/BaseCarvingPerformer.cpp
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/SurfaceCarvingPerformer.cpp
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/BurningPerformer.cpp
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/SimpleCarvingPerformer.cpp

${INFINYTOOLKIT_SRC_DIR}/CarvingTools/BurningPerformer.cpp
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/SurfaceCarvingPerformer.cpp
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/HapticCarvingManager.cpp

${INFINYTOOLKIT_SRC_DIR}/BruteForceFeedback.cpp
)

Expand All @@ -71,10 +71,12 @@ if (MeshRefinement_FOUND)
message("MeshRefinement plugin found - Adding it to ${PROJECT_NAME}")
list(APPEND HEADER_FILES
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/RefineCarvingPerformer.h
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/CuttingPerformer.h
)

list(APPEND SOURCE_FILES
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/RefineCarvingPerformer.cpp
${INFINYTOOLKIT_SRC_DIR}/CarvingTools/CuttingPerformer.cpp
)

add_definitions(-DHAS_MESHREFINEMENT_PLUGIN)
Expand Down
29 changes: 22 additions & 7 deletions src/InfinyToolkit/CarvingTools/AdvancedCarvingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

#ifdef HAS_MESHREFINEMENT_PLUGIN
#include <InfinyToolkit/CarvingTools/RefineCarvingPerformer.h>
#include <InfinyToolkit/CarvingTools/CuttingPerformer.h>
#endif

#include <sofa/core/behavior/BaseMechanicalState.h>
Expand All @@ -65,6 +66,7 @@ AdvancedCarvingManager::AdvancedCarvingManager()
, d_active( initData(&d_active, false, "active", "Activate this object.\nNote that this can be dynamically controlled by using a key") )
, d_carvingWithBurning(initData(&d_carvingWithBurning, true, "carvingWithBurning", "Activate this object.\nNote that this can be dynamically controlled by using a key"))
, d_carvingWithRefinement(initData(&d_carvingWithRefinement, false, "carvingWithRefinement", "Activate this object.\nNote that this can be dynamically controlled by using a key"))
, 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."))
Expand Down Expand Up @@ -187,11 +189,20 @@ void AdvancedCarvingManager::bwdInit()
m_carvingPerformer.push_back(new BurningPerformer(topo, this));
}

if (d_carvingWithRefinement.getValue()) {
if (d_carvingWithRefinement.getValue())
{
#ifdef HAS_MESHREFINEMENT_PLUGIN
m_carvingPerformer.push_back(new RefineCarvingPerformer(topo, this));
#else
msg_warning() << "Option carvingWithRefinement require MeshRefienement plugin. Please check https://www.sofa-framework.org/applications/marketplace/cutting-mesh-refinement/ for more information.";
#endif
}
else if (d_cuttingMode.getValue())
{
#ifdef HAS_MESHREFINEMENT_PLUGIN
m_carvingPerformer.push_back(new CuttingPerformer(topo, this));
#else
msg_warning() << "Option cutting require MeshRefienement plugin. Please check https://www.sofa-framework.org/applications/marketplace/cutting-mesh-refinement/ for more information.";
#endif
}
else
Expand Down Expand Up @@ -338,11 +349,11 @@ void AdvancedCarvingManager::filterCollision()
carvingPerformer->filterContacts();
}

// process the collision
for (auto carvingPerformer : m_carvingPerformer)
{
carvingPerformer->runPerformer();
}
//// process the collision
//for (auto carvingPerformer : m_carvingPerformer)
//{
// carvingPerformer->runPerformer();
//}
}


Expand All @@ -367,7 +378,11 @@ void AdvancedCarvingManager::handleEvent(sofa::core::objectmodel::Event* event)
if (ev->getKey() == 'C')
{
msg_warning() << "Burn, baby burn!";
d_active.setValue(true);
//d_active.setValue(true);
for (auto carvingPerformer : m_carvingPerformer)
{
carvingPerformer->runPerformer();
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/InfinyToolkit/CarvingTools/AdvancedCarvingManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class SOFA_INFINYTOOLKIT_API AdvancedCarvingManager : public core::behavior::Bas
Data < bool > d_active;
Data < bool > d_carvingWithBurning;
Data < bool > d_carvingWithRefinement;
Data < bool > d_cuttingMode;


/// Collision distance at which cavring will start. Equal to contactDistance by default.
Expand Down
163 changes: 163 additions & 0 deletions src/InfinyToolkit/CarvingTools/CuttingPerformer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*****************************************************************************
* - Copyright (C) - 2020 - InfinyTech3D - *
* *
* This file is part of the InfinyToolkit plugin for the SOFA framework *
* *
* Commercial License Usage: *
* Licensees holding valid commercial license from InfinyTech3D may use this *
* file in accordance with the commercial license agreement provided with *
* the Software or, alternatively, in accordance with the terms contained in *
* a written agreement between you and InfinyTech3D. For further information *
* on the licensing terms and conditions, contact: contact@infinytech3d.com *
* *
* GNU General Public License Usage: *
* Alternatively, this file may be used under the terms of the GNU General *
* Public License version 3. The licenses are as published by the Free *
* Software Foundation and appearing in the file LICENSE.GPL3 included in *
* the packaging of this file. Please review the following information to *
* ensure the GNU General Public License requirements will be met: *
* https://www.gnu.org/licenses/gpl-3.0.html. *
* *
* Authors: see Authors.txt *
* Further information: https://infinytech3d.com *
****************************************************************************/

#include <InfinyToolkit/CarvingTools/CuttingPerformer.h>
#include <InfinyToolkit/CarvingTools/AdvancedCarvingManager.h>

#include <sofa/component/statecontainer/MechanicalObject.h>

namespace sofa::infinytoolkit
{

CuttingPerformer::CuttingPerformer(TetrahedronSetTopologyContainer::SPtr topo, AdvancedCarvingManager* _carvingMgr)
: BaseCarvingPerformer(topo, _carvingMgr)
{

}


bool CuttingPerformer::initPerformer()
{
m_topoModif = m_topologyCon->getContext()->get<TetrahedronSetTopologyModifier>();

if (m_topoModif == nullptr) {
msg_error("CuttingPerformer") << "InitPerformer failed, no TetrahedronSetTopologyModifier found in Node: " << m_topologyCon->getContext()->getName();
return false;
}

if (m_tetraCuttingMgr == nullptr)
{
m_tetraCuttingMgr = std::make_unique<sofa::meshrefinement::TetrahedronCuttingManager<sofa::defaulttype::Vec3Types> >();
m_tetraCuttingMgr->init(m_topologyCon->getContext());
m_tetraCuttingMgr->activateLogs(m_topologyCon->f_printLog.getValue());

//if (d_surfaceCut.getValue())
//{
// const std::string& textName = d_textureName.getValue();
// if (!textName.empty())
// m_tetraCuttingMgr->setCutTextureName(textName);
//}
}

return true;
}


void CuttingPerformer::filterContacts()
{
// Create Cut quad
fixed_array<Vec3, 4> m_planPositions;

// we use the cutting tool points to detect the direction and length of cut
const SReal& _carvingDistance = m_carvingMgr->d_carvingDistance.getValue();

// 1- get barycenter and cutting position
std::vector<Vec3> cutPositions;
Vec3 bary = Vec3(0, 0, 0);
Vec3 cutDir = Vec3(0, 0, 0);
for (const contactInfo* cInfo : m_triangleContacts)
{
cutPositions.push_back(cInfo->pointA);
bary += cInfo->pointA;
cutDir += cInfo->pointB - cInfo->pointA;
}

if (cutPositions.empty())
return;

bary /= cutPositions.size();
cutDir /= cutPositions.size();
cutDir.normalize();

// 2- get cut extremity
SReal maxLength = 0.0;
for (const contactInfo* cInfo : m_triangleContacts)
{
Vec3 toolDir = cInfo->pointA - bary;
SReal length2 = toolDir.norm2();
if (maxLength < length2)
{
maxLength = length2;
m_planPositions[0] = bary + toolDir;
m_planPositions[1] = bary - toolDir;
}
}

m_planPositions[2] = m_planPositions[1] + cutDir * _carvingDistance;
m_planPositions[3] = m_planPositions[0] + cutDir * _carvingDistance;
Vec3 m_planNormal = (m_planPositions[1] - m_planPositions[0]).cross(cutDir);

// Test all tetra
m_tetraCuttingMgr->createCutPlanPath(m_planPositions, m_planNormal, _carvingDistance * 10);
}

bool CuttingPerformer::runPerformer()
{
m_tetraCuttingMgr->processCut(1);

m_triangleContacts.clear();
m_pointContacts.clear();
return true;
}


void CuttingPerformer::draw(const core::visual::VisualParams* vparams)
{
if (!m_triangleContacts.empty())
{
const SReal& _carvingDistance = m_carvingMgr->d_carvingDistance.getValue();
const SReal& _refineDistance = m_carvingMgr->d_refineDistance.getValue();

for (const contactInfo* cInfo : m_triangleContacts)
{
std::vector<Vec3> pos;
sofa::core::behavior::BaseMechanicalState* mstate = m_topologyCon->getContext()->getMechanicalState();
sofa::core::topology::Topology::Triangle tri = m_topologyCon->getTriangle(cInfo->elemId);

for (unsigned int j = 0; j < 3; j++) {
pos.push_back(Vec3(mstate->getPX(tri[j]), mstate->getPY(tri[j]), mstate->getPZ(tri[j])));
}

sofa::type::RGBAColor color4(1.0f, 0.0, 0.0f, 1.0);
if (cInfo->dist < _carvingDistance)
color4 = sofa::type::RGBAColor(0.0f, 1.0, 0.0f, 1.0);
else if (cInfo->dist < _refineDistance)
color4 = sofa::type::RGBAColor(0.0f, 0.0, 1.0f, 1.0);

vparams->drawTool()->drawTriangle(pos[0], pos[1], pos[2], cInfo->normal, color4);

vparams->drawTool()->drawSphere(cInfo->pointB, float(_carvingDistance), sofa::type::RGBAColor(1.0f, 0.0f, 0.0f, 0.8f));
vparams->drawTool()->drawSphere(cInfo->pointA, float(_carvingDistance), sofa::type::RGBAColor(0.0f, 1.0f, 0.0f, 0.8f));
}

m_tetraCuttingMgr->drawCutPlan(vparams);
m_tetraCuttingMgr->drawDebugCut(vparams);

}



}

} // namespace sofa::infinytoolkit
59 changes: 59 additions & 0 deletions src/InfinyToolkit/CarvingTools/CuttingPerformer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*****************************************************************************
* - Copyright (C) - 2020 - InfinyTech3D - *
* *
* This file is part of the InfinyToolkit plugin for the SOFA framework *
* *
* Commercial License Usage: *
* Licensees holding valid commercial license from InfinyTech3D may use this *
* file in accordance with the commercial license agreement provided with *
* the Software or, alternatively, in accordance with the terms contained in *
* a written agreement between you and InfinyTech3D. For further information *
* on the licensing terms and conditions, contact: contact@infinytech3d.com *
* *
* GNU General Public License Usage: *
* Alternatively, this file may be used under the terms of the GNU General *
* Public License version 3. The licenses are as published by the Free *
* Software Foundation and appearing in the file LICENSE.GPL3 included in *
* the packaging of this file. Please review the following information to *
* ensure the GNU General Public License requirements will be met: *
* https://www.gnu.org/licenses/gpl-3.0.html. *
* *
* Authors: see Authors.txt *
* Further information: https://infinytech3d.com *
****************************************************************************/
#pragma once

#include <InfinyToolkit/CarvingTools/BaseCarvingPerformer.h>
#include <MeshRefinement/TetrahedronCuttingManager.h>
#include <sofa/component/topology/container/dynamic/TetrahedronSetTopologyModifier.h>

namespace sofa::infinytoolkit
{
using namespace sofa::core::topology;
using namespace sofa::component::topology::container::dynamic;

class SOFA_INFINYTOOLKIT_API CuttingPerformer : public BaseCarvingPerformer
{
public:
CuttingPerformer(TetrahedronSetTopologyContainer::SPtr topo, AdvancedCarvingManager* _carvingMgr);

virtual ~CuttingPerformer() = default;

bool initPerformer() override;

void filterContacts() override;

bool runPerformer() override;

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

private:
TetrahedronSetTopologyModifier::SPtr m_topoModif = nullptr;

std::unique_ptr<sofa::meshrefinement::TetrahedronCuttingManager<sofa::defaulttype::Vec3Types> > m_tetraCuttingMgr = nullptr;

std::vector<Index> m_tetra2Remove;
};

} // namespace sofa::infinytoolkit