diff --git a/SofaKernel/modules/SofaMeshCollision/TriangleModel.h b/SofaKernel/modules/SofaMeshCollision/TriangleModel.h index 491d4042e35..4871c60b868 100644 --- a/SofaKernel/modules/SofaMeshCollision/TriangleModel.h +++ b/SofaKernel/modules/SofaMeshCollision/TriangleModel.h @@ -100,6 +100,11 @@ class TTriangle : public core::TCollisionElementIterator< TTriangleModel class SOFA_MESH_COLLISION_API TTriangleModel : public core::CollisionModel { @@ -133,33 +138,39 @@ class SOFA_MESH_COLLISION_API TTriangleModel : public core::CollisionModel enum { NBARY = 2 }; - Data bothSide; ///< to activate collision on both side of the triangle model -protected: - VecDeriv normals; + Data d_bothSide; ///< to activate collision on both side of the triangle model + Data d_computeNormals; ///< set to false to disable computation of triangles normal - const sofa::core::topology::BaseMeshTopology::SeqTriangles* triangles; +protected: + core::behavior::MechanicalState* m_mstate; ///< Pointer to the corresponding MechanicalState + sofa::core::topology::BaseMeshTopology* m_topology; ///< Pointer to the corresponding Topology - sofa::core::topology::BaseMeshTopology::SeqTriangles mytriangles; + VecDeriv m_normals; ///< Vector of normal direction per triangle. - bool needsUpdate; - virtual void updateFromTopology(); - virtual void updateFlags(int ntri=-1); - virtual void updateNormals(); - int getTriangleFlags(sofa::core::topology::BaseMeshTopology::TriangleID i); + /** Pointer to the triangle array of this collision model. + * Will point directly to the topology triangle buffer if only triangles are present. If topology is using/mixing quads and triangles, + * This pointer will target \sa m_internalTriangles + * @brief m_triangles + */ + const sofa::core::topology::BaseMeshTopology::SeqTriangles* m_triangles; - core::behavior::MechanicalState* mstate; - Data computeNormals; ///< set to false to disable computation of triangles normal - int meshRevision; + sofa::core::topology::BaseMeshTopology::SeqTriangles m_internalTriangles; ///< Internal Buffer of triangles to combine quads splitted and other triangles. - sofa::core::topology::BaseMeshTopology* _topology; + bool m_needsUpdate; ///< parameter storing the info boundingTree has to be recomputed. + int m_topologyRevision; ///< internal revision number to check if topology has changed. - PointModel* mpoints; + PointModel* m_pointModels; TriangleLocalMinDistanceFilter *m_lmdFilter; protected: TTriangleModel(); + + virtual void updateFromTopology(); + virtual void updateFlags(int ntri=-1); + virtual void updateNormals(); + public: virtual void init() override; @@ -177,14 +188,13 @@ class SOFA_MESH_COLLISION_API TTriangleModel : public core::CollisionModel virtual bool canCollideWithElement(int index, CollisionModel* model2, int index2) override; - virtual void handleTopologyChange() override; - - core::behavior::MechanicalState* getMechanicalState() { return mstate; } - const core::behavior::MechanicalState* getMechanicalState() const { return mstate; } + core::behavior::MechanicalState* getMechanicalState() { return m_mstate; } + const core::behavior::MechanicalState* getMechanicalState() const { return m_mstate; } const VecCoord& getX() const { return(getMechanicalState()->read(core::ConstVecCoordId::position())->getValue()); } - const sofa::core::topology::BaseMeshTopology::SeqTriangles& getTriangles() const { return *triangles; } - const VecDeriv& getNormals() const { return normals; } + const sofa::core::topology::BaseMeshTopology::SeqTriangles& getTriangles() const { return *m_triangles; } + const VecDeriv& getNormals() const { return m_normals; } + int getTriangleFlags(sofa::core::topology::BaseMeshTopology::TriangleID i); TriangleLocalMinDistanceFilter *getFilter() const; @@ -216,6 +226,9 @@ class SOFA_MESH_COLLISION_API TTriangleModel : public core::CollisionModel virtual void computeBBox(const core::ExecParams* params, bool onlyVisible=false) override; }; + + + template inline TTriangle::TTriangle(ParentModel* model, int index) : core::TCollisionElementIterator(model, index) @@ -232,57 +245,57 @@ inline TTriangle::TTriangle(ParentModel* model, int index, helper::Re {} template -inline const typename DataTypes::Coord& TTriangle::p1() const { return this->model->mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->triangles))[this->index][0]]; } +inline const typename DataTypes::Coord& TTriangle::p1() const { return this->model->m_mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->m_triangles))[this->index][0]]; } template -inline const typename DataTypes::Coord& TTriangle::p2() const { return this->model->mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->triangles))[this->index][1]]; } +inline const typename DataTypes::Coord& TTriangle::p2() const { return this->model->m_mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->m_triangles))[this->index][1]]; } template -inline const typename DataTypes::Coord& TTriangle::p3() const { return this->model->mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->triangles))[this->index][2]]; } +inline const typename DataTypes::Coord& TTriangle::p3() const { return this->model->m_mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->m_triangles))[this->index][2]]; } template inline const typename DataTypes::Coord& TTriangle::p(int i) const { - return this->model->mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->triangles))[this->index][i]]; + return this->model->m_mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->m_triangles))[this->index][i]]; } template inline const typename DataTypes::Coord& TTriangle::operator[](int i) const { - return this->model->mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->triangles))[this->index][i]]; + return this->model->m_mstate->read(core::ConstVecCoordId::position())->getValue()[(*(this->model->m_triangles))[this->index][i]]; } template -inline const typename DataTypes::Coord& TTriangle::p1Free() const { return (*this->model->mstate->read(sofa::core::ConstVecCoordId::freePosition())->getValue())[(*(this->model->triangles))[this->index][0]]; } +inline const typename DataTypes::Coord& TTriangle::p1Free() const { return (*this->model->m_mstate->read(sofa::core::ConstVecCoordId::freePosition())->getValue())[(*(this->model->m_triangles))[this->index][0]]; } template -inline const typename DataTypes::Coord& TTriangle::p2Free() const { return (*this->model->mstate->read(sofa::core::ConstVecCoordId::freePosition())->getValue())[(*(this->model->triangles))[this->index][1]]; } +inline const typename DataTypes::Coord& TTriangle::p2Free() const { return (*this->model->m_mstate->read(sofa::core::ConstVecCoordId::freePosition())->getValue())[(*(this->model->m_triangles))[this->index][1]]; } template -inline const typename DataTypes::Coord& TTriangle::p3Free() const { return (*this->model->mstate->read(sofa::core::ConstVecCoordId::freePosition())->getValue())[(*(this->model->triangles))[this->index][2]]; } +inline const typename DataTypes::Coord& TTriangle::p3Free() const { return (*this->model->m_mstate->read(sofa::core::ConstVecCoordId::freePosition())->getValue())[(*(this->model->m_triangles))[this->index][2]]; } template -inline int TTriangle::p1Index() const { return (*(this->model->triangles))[this->index][0]; } +inline int TTriangle::p1Index() const { return (*(this->model->m_triangles))[this->index][0]; } template -inline int TTriangle::p2Index() const { return (*(this->model->triangles))[this->index][1]; } +inline int TTriangle::p2Index() const { return (*(this->model->m_triangles))[this->index][1]; } template -inline int TTriangle::p3Index() const { return (*(this->model->triangles))[this->index][2]; } +inline int TTriangle::p3Index() const { return (*(this->model->m_triangles))[this->index][2]; } template -inline const typename DataTypes::Deriv& TTriangle::v1() const { return (this->model->mstate->read(core::ConstVecDerivId::velocity())->getValue())[(*(this->model->triangles))[this->index][0]]; } +inline const typename DataTypes::Deriv& TTriangle::v1() const { return (this->model->m_mstate->read(core::ConstVecDerivId::velocity())->getValue())[(*(this->model->m_triangles))[this->index][0]]; } template -inline const typename DataTypes::Deriv& TTriangle::v2() const { return this->model->mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(this->model->triangles))[this->index][1]]; } +inline const typename DataTypes::Deriv& TTriangle::v2() const { return this->model->m_mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(this->model->m_triangles))[this->index][1]]; } template -inline const typename DataTypes::Deriv& TTriangle::v3() const { return this->model->mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(this->model->triangles))[this->index][2]]; } +inline const typename DataTypes::Deriv& TTriangle::v3() const { return this->model->m_mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(this->model->m_triangles))[this->index][2]]; } template -inline const typename DataTypes::Deriv& TTriangle::v(int i) const { return this->model->mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(this->model->triangles))[this->index][i]]; } +inline const typename DataTypes::Deriv& TTriangle::v(int i) const { return this->model->m_mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(this->model->m_triangles))[this->index][i]]; } template -inline const typename DataTypes::Deriv& TTriangle::n() const { return this->model->normals[this->index]; } +inline const typename DataTypes::Deriv& TTriangle::n() const { return this->model->m_normals[this->index]; } template -inline typename DataTypes::Deriv& TTriangle::n() { return this->model->normals[this->index]; } +inline typename DataTypes::Deriv& TTriangle::n() { return this->model->m_normals[this->index]; } template inline int TTriangle::flags() const { return this->model->getTriangleFlags(this->index); } template -inline bool TTriangle::hasFreePosition() const { return this->model->mstate->read(core::ConstVecCoordId::freePosition())->isSet(); } +inline bool TTriangle::hasFreePosition() const { return this->model->m_mstate->read(core::ConstVecCoordId::freePosition())->isSet(); } template -inline typename DataTypes::Deriv TTriangleModel::velocity(int index) const { return (mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(triangles))[index][0]] + mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(triangles))[index][1]] + - mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(triangles))[index][2]])/((Real)(3.0)); } +inline typename DataTypes::Deriv TTriangleModel::velocity(int index) const { return (m_mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(m_triangles))[index][0]] + m_mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(m_triangles))[index][1]] + + m_mstate->read(core::ConstVecDerivId::velocity())->getValue()[(*(m_triangles))[index][2]])/((Real)(3.0)); } typedef TTriangleModel TriangleModel; typedef TTriangle Triangle; diff --git a/SofaKernel/modules/SofaMeshCollision/TriangleModel.inl b/SofaKernel/modules/SofaMeshCollision/TriangleModel.inl index 92a978760fe..dfe469b5a88 100644 --- a/SofaKernel/modules/SofaMeshCollision/TriangleModel.inl +++ b/SofaKernel/modules/SofaMeshCollision/TriangleModel.inl @@ -49,13 +49,16 @@ namespace collision template TTriangleModel::TTriangleModel() - : bothSide(initData(&bothSide, false, "bothSide", "activate collision on both side of the triangle model") ) - , mstate(NULL) - , computeNormals(initData(&computeNormals, true, "computeNormals", "set to false to disable computation of triangles normal")) - , meshRevision(-1) + : d_bothSide(initData(&d_bothSide, false, "bothSide", "activate collision on both side of the triangle model") ) + , d_computeNormals(initData(&d_computeNormals, true, "computeNormals", "set to false to disable computation of triangles normal")) + , m_mstate(NULL) + , m_topology(NULL) + , m_needsUpdate(true) + , m_topologyRevision(-1) + , m_pointModels(NULL) , m_lmdFilter(NULL) { - triangles = &mytriangles; + m_triangles = &m_internalTriangles; enum_type = TRIANGLE_TYPE; } @@ -63,31 +66,37 @@ template void TTriangleModel::resize(int size) { this->core::CollisionModel::resize(size); - //helper::vector& e = *(elems.beginEdit()); - //e.resize(size); - //elems.endEdit(); - normals.resize(size); + m_normals.resize(size); } template void TTriangleModel::init() { - _topology = this->getContext()->getMeshTopology(); + m_topology = this->getContext()->getMeshTopology(); + // TODO epernod 2019-01-21: Check if this call super is needed. this->CollisionModel::init(); - mstate = dynamic_cast< core::behavior::MechanicalState* > (this->getContext()->getMechanicalState()); + m_mstate = dynamic_cast< core::behavior::MechanicalState* > (this->getContext()->getMechanicalState()); - this->getContext()->get(mpoints); + this->getContext()->get(m_pointModels); - if (mstate==NULL) + // Check object pointer access + bool modelsOk = true; + if (m_mstate == NULL) { - serr << "TriangleModel requires a Vec3 Mechanical Model" << sendl; - return; + msg_error() << "No MechanicalObject found. TriangleModel requires a Vec3 Mechanical Model in the same Node."; + modelsOk = false; } - if (!_topology) + if (m_topology == NULL) { - serr << "TriangleModel requires a BaseMeshTopology" << sendl; + msg_error() << "No Topology found. TriangleModel requires a Triangular Topology in the same Node."; + modelsOk = false; + } + + if (!modelsOk) + { + this->m_componentstate = sofa::core::objectmodel::ComponentState::Invalid; return; } @@ -97,13 +106,19 @@ void TTriangleModel::init() m_lmdFilter = node->getNodeObject< TriangleLocalMinDistanceFilter >(); } - //sout << "INFO_print : Col - init TRIANGLE " << sendl; - sout << "TriangleModel: initially "<<_topology->getNbTriangles()<<" triangles." << sendl; - triangles = &_topology->getTriangles(); - resize(_topology->getNbTriangles()); - - updateFromTopology(); - updateNormals(); + // check if topology is using triangles and quads at the same time. + if (m_topology->getNbQuads() != 0) + { + updateFromTopology(); // in this case, need to create a single buffer with both topology + // updateNormals will be call in updateFromTopology + } + else + { + // just redirect to the topology buffer. + m_triangles = &m_topology->getTriangles(); + resize(m_topology->getNbTriangles()); + updateNormals(); + } } template @@ -118,89 +133,90 @@ void TTriangleModel::updateNormals() t.n() = cross(pt2-pt1,pt3-pt1); t.n().normalize(); - //sout << i << " " << t.n() << sendl; } } template void TTriangleModel::updateFromTopology() { - // needsUpdate = false; - const unsigned npoints = mstate->getSize(); - const unsigned ntris = _topology->getNbTriangles(); - const unsigned nquads = _topology->getNbQuads(); - const unsigned newsize = ntris+2*nquads; - - int revision = _topology->getRevision(); - if (newsize==(unsigned)size && revision == meshRevision) + int revision = m_topology->getRevision(); + if (revision == m_topologyRevision) return; - meshRevision = revision; - needsUpdate=true; + m_topologyRevision = revision; - resize(newsize); + const unsigned nquads = m_topology->getNbQuads(); + const unsigned ntris = m_topology->getNbTriangles(); - if (newsize == ntris) + if (nquads == 0) // only triangles { - // no need to copy the triangle indices - triangles = & _topology->getTriangles(); + resize(ntris); + m_triangles = & m_topology->getTriangles(); } else { - triangles = &mytriangles; - mytriangles.resize(newsize); + const unsigned newsize = ntris+2*nquads; + const unsigned npoints = m_mstate->getSize(); + + m_triangles = &m_internalTriangles; + m_internalTriangles.resize(newsize); + resize(newsize); + int index = 0; for (unsigned i=0; igetTriangle(i); + core::topology::BaseMeshTopology::Triangle idx = m_topology->getTriangle(i); if (idx[0] >= npoints || idx[1] >= npoints || idx[2] >= npoints) { - serr << "ERROR: Out of range index in triangle "<= npoints) idx[0] = npoints-1; if (idx[1] >= npoints) idx[1] = npoints-1; if (idx[2] >= npoints) idx[2] = npoints-1; } - mytriangles[index] = idx; + m_internalTriangles[index] = idx; ++index; } for (unsigned i=0; igetQuad(i); + core::topology::BaseMeshTopology::Quad idx = m_topology->getQuad(i); if (idx[0] >= npoints || idx[1] >= npoints || idx[2] >= npoints || idx[3] >= npoints) { - serr << "ERROR: Out of range index in quad "<= npoints) idx[0] = npoints-1; if (idx[1] >= npoints) idx[1] = npoints-1; if (idx[2] >= npoints) idx[2] = npoints-1; if (idx[3] >= npoints) idx[3] = npoints-1; } - mytriangles[index][0] = idx[1]; - mytriangles[index][1] = idx[2]; - mytriangles[index][2] = idx[0]; + m_internalTriangles[index][0] = idx[1]; + m_internalTriangles[index][1] = idx[2]; + m_internalTriangles[index][2] = idx[0]; ++index; - mytriangles[index][0] = idx[3]; - mytriangles[index][1] = idx[0]; - mytriangles[index][2] = idx[2]; + m_internalTriangles[index][0] = idx[3]; + m_internalTriangles[index][1] = idx[0]; + m_internalTriangles[index][2] = idx[2]; ++index; } } updateFlags(); updateNormals(); + + // topology has changed, force boudingTree recomputation + m_needsUpdate = true; } template void TTriangleModel::updateFlags(int /*ntri*/) { #if 0 - if (ntri < 0) ntri = triangles->size(); - //VecCoord& x =mstate->read(core::ConstVecCoordId::position())->getValue(); - //VecDeriv& v = mstate->read(core::ConstVecDerivId::velocity())->getValue(); - vector pflags(mstate->getSize()); + if (ntri < 0) ntri = m_triangles->size(); + //VecCoord& x =m_mstate->read(core::ConstVecCoordId::position())->getValue(); + //VecDeriv& v = m_mstate->read(core::ConstVecDerivId::velocity())->getValue(); + vector pflags(m_mstate->getSize()); std::set > eflags; - for (unsigned i=0; isize(); i++) + for (unsigned i=0; isize(); i++) { int f = 0; - topology::Triangle t = (*triangles)[i]; + topology::Triangle t = (*m_triangles)[i]; if (!pflags[t[0]]) { f |= FLAG_P1; @@ -233,374 +249,6 @@ void TTriangleModel::updateFlags(int /*ntri*/) #endif } -template -void TTriangleModel::handleTopologyChange() -{ - - // We use the same triangle array as the topology -> only resize and recompute flags - std::list::const_iterator itBegin=_topology->beginChange(); - std::list::const_iterator itEnd=_topology->endChange(); - //elems.handleTopologyEvents(itBegin,itEnd); - - while( itBegin != itEnd ) - { - core::topology::TopologyChangeType changeType = (*itBegin)->getChangeType(); - - switch( changeType ) - { - - - case core::topology::ENDING_EVENT: - { - updateFromTopology(); - - sout << "TriangleModel: now "<<_topology->getNbTriangles()<<" triangles." << sendl; - resize(_topology->getNbTriangles()); - needsUpdate=true; - updateFlags(); - break; - } - /* - case core::topology::TRIANGLESADDED: - { - //sout << "INFO_print : Vis - TRIANGLESADDED" << sendl; - const sofa::component::topology::TrianglesAdded *ta=static_cast< const sofa::component::topology::TrianglesAdded * >( *itBegin ); - for (unsigned int i=0;igetNbAddedTriangles();++i) { - Triangle t(this, size - ta->getNbAddedTriangles() + i); - const defaulttype::Vector3& pt1 = t.p1(); - const defaulttype::Vector3& pt2 = t.p2(); - const defaulttype::Vector3& pt3 = t.p3(); - t.n() = cross(pt2-pt1,pt3-pt1); - t.n().normalize(); - } - break; - }*/ - default: break; - } - ++itBegin; - } - return; -#if 0 - sofa::core::topology::TopologyModifier* topoMod; - this->getContext()->get(topoMod); - - if (topoMod) // dynamic topology - { - - std::list::const_iterator itBegin=_topology->beginChange(); - std::list::const_iterator itEnd=_topology->endChange(); - - - while( itBegin != itEnd ) - { - core::topology::TopologyChangeType changeType = (*itBegin)->getChangeType(); - - switch( changeType ) - { - - - case core::topology::ENDING_EVENT: - { - //sout << "INFO_print : Col - ENDING_EVENT" << sendl; - needsUpdate=true; - break; - } - - - case core::topology::TRIANGLESADDED: - { - //sout << "INFO_print : Col - TRIANGLESADDED" << sendl; - TriangleInfo t; - const sofa::component::topology::TrianglesAdded *ta=static_cast< const sofa::component::topology::TrianglesAdded * >( *itBegin ); - for (unsigned int i=0; igetNbAddedTriangles(); ++i) - { - mytriangles.push_back(ta->triangleArray[i]); - } - resize( mytriangles.size()); - needsUpdate=true; - - break; - } - - case core::topology::TRIANGLESREMOVED: - { - //sout << "INFO_print : Col - TRIANGLESREMOVED" << sendl; - unsigned int last; - unsigned int ind_last; - - last= _topology->getNbPoints() - 1; - - const sofa::helper::vector &tab = ( static_cast< const sofa::component::topology::TrianglesRemoved *>( *itBegin ) )->getArray(); - - TriangleInfo tmp; - topology::Triangle tmp2; - - for (unsigned int i = 0; i getNbTriangles()>0) - { - - unsigned int last = _topology->getNbPoints() -1; - - unsigned int i,j; - const sofa::helper::vector tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray(); - - sofa::helper::vector lastIndexVec; - for(unsigned int i_init = 0; i_init < tab.size(); ++i_init) - { - - lastIndexVec.push_back(last - i_init); - } - - for ( i = 0; i < tab.size(); ++i) - { - unsigned int i_next = i; - bool is_reached = false; - while( (!is_reached) && (i_next < lastIndexVec.size() - 1)) - { - - i_next += 1 ; - is_reached = is_reached || (lastIndexVec[i_next] == tab[i]); - } - - if(is_reached) - { - - lastIndexVec[i_next] = lastIndexVec[i]; - - } - - const sofa::helper::vector &shell=_topology->getTrianglesAroundVertex(lastIndexVec[i]); - for (j=0; jgetNbTriangles()>0) - { - - unsigned int i; - - const sofa::helper::vector tab = ( static_cast< const sofa::component::topology::PointsRenumbering * >( *itBegin ) )->getinv_IndexArray(); - - for ( i = 0; i < mytriangles.size(); ++i) - { - mytriangles[i][0] = tab[mytriangles[i][0]]; - mytriangles[i][1] = tab[mytriangles[i][1]]; - mytriangles[i][2] = tab[mytriangles[i][2]]; - } - - } - - //} - - break; - - } - - default: - // Ignore events that are not Triangle related. - break; - }; // switch( changeType ) - - mytriangles.resize( elems.size() ); // not necessary - resize( elems.size() ); // not necessary - - ++itBegin; - } // while( changeIt != last; ) - } - if (needsUpdate) - { - updateFlags(); - } -#endif -} - -template -void TTriangleModel::draw(const core::visual::VisualParams* vparams ,int index) -{ - Element t(this,index); - - vparams->drawTool()->setPolygonMode(0,vparams->displayFlags().getShowWireFrame()); - vparams->drawTool()->setLightingEnabled(true); - vparams->drawTool()->drawTriangle( t.p1(), t.p2(), t.p3(), t.n() ); - vparams->drawTool()->setLightingEnabled(false); - -} - - -template -void TTriangleModel::draw(const core::visual::VisualParams* vparams) -{ - if (vparams->displayFlags().getShowCollisionModels()) - { - //if( size != _topology->getNbTriangles()) - // updateFromTopology(); - - if (bothSide.getValue() || vparams->displayFlags().getShowWireFrame()) - vparams->drawTool()->setPolygonMode(0,vparams->displayFlags().getShowWireFrame()); - else - { - vparams->drawTool()->setPolygonMode(2,true); - vparams->drawTool()->setPolygonMode(1,false); - } - - std::vector< defaulttype::Vector3 > points; - std::vector< defaulttype::Vec<3,int> > indices; - std::vector< defaulttype::Vector3 > normals; - int index=0; - for (int i=0; i(index,index+1,index+2)); - index+=3; - } - - vparams->drawTool()->setLightingEnabled(true); - vparams->drawTool()->drawTriangles(points, indices, normals, defaulttype::Vec<4,float>(getColor4f())); - vparams->drawTool()->setLightingEnabled(false); - vparams->drawTool()->setPolygonMode(0,false); - - - if (vparams->displayFlags().getShowNormals()) - { - std::vector< defaulttype::Vector3 > points; - for (int i=0; idrawTool()->drawLines(points, 1, defaulttype::Vec<4,float>(1,1,1,1)); - - } - } - if (getPrevious()!=NULL && vparams->displayFlags().getShowBoundingCollisionModels()) - getPrevious()->draw(vparams); -} - template bool TTriangleModel::canCollideWithElement(int index, CollisionModel* model2, int index2) @@ -609,7 +257,7 @@ bool TTriangleModel::canCollideWithElement(int index, CollisionModel* if (this->getContext() != model2->getContext()) return true; Element t(this,index); - if (model2 == mpoints) + if (model2 == m_pointModels) { // if point belong to the triangle, return false if ( index2==t.p1Index() || index2==t.p2Index() || index2==t.p3Index()) @@ -644,17 +292,21 @@ void TTriangleModel::computeBoundingTree(int maxDepth) { CubeModel* cubeModel = createPrevious(); - if (needsUpdate && !cubeModel->empty()) cubeModel->resize(0); + // check first that topology didn't changed + if (m_topology->getRevision() != m_topologyRevision) + updateFromTopology(); - if (!isMoving() && !cubeModel->empty() && !needsUpdate) return; // No need to recompute BBox if immobile + if (m_needsUpdate && !cubeModel->empty()) cubeModel->resize(0); - needsUpdate=false; - defaulttype::Vector3 minElem, maxElem; - const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); + if (!isMoving() && !cubeModel->empty() && !m_needsUpdate) return; // No need to recompute BBox if immobile nor if mesh didn't change. - const bool calcNormals = computeNormals.getValue(); + // set to false to avoid excesive loop + m_needsUpdate=false; + defaulttype::Vector3 minElem, maxElem; + const VecCoord& x = this->m_mstate->read(core::ConstVecCoordId::position())->getValue(); + const bool calcNormals = d_computeNormals.getValue(); cubeModel->resize(size); // size = number of triangles if (!empty()) @@ -663,6 +315,7 @@ void TTriangleModel::computeBoundingTree(int maxDepth) for (int i=0; i void TTriangleModel::computeContinuousBoundingTree(double dt, int maxDepth) { CubeModel* cubeModel = createPrevious(); - //updateFromTopology(); - if (needsUpdate) cubeModel->resize(0); - if (!isMoving() && !cubeModel->empty() && !needsUpdate) return; // No need to recompute BBox if immobile - needsUpdate=false; + // check first that topology didn't changed + if (m_topology->getRevision() != m_topologyRevision) + updateFromTopology(); + + if (m_needsUpdate) cubeModel->resize(0); + if (!isMoving() && !cubeModel->empty() && !m_needsUpdate) return; // No need to recompute BBox if immobile nor if mesh didn't change. + + m_needsUpdate=false; defaulttype::Vector3 minElem, maxElem; cubeModel->resize(size); @@ -768,22 +425,22 @@ template int TTriangleModel::getTriangleFlags(Topology::TriangleID i) { int f = 0; - sofa::core::topology::BaseMeshTopology::Triangle t = (*triangles)[i]; + sofa::core::topology::BaseMeshTopology::Triangle t = (*m_triangles)[i]; - if (i < _topology->getNbTriangles()) + if (i < m_topology->getNbTriangles()) { for (unsigned int j=0; j<3; ++j) { - const sofa::core::topology::BaseMeshTopology::TrianglesAroundVertex& tav = _topology->getTrianglesAroundVertex(t[j]); + const sofa::core::topology::BaseMeshTopology::TrianglesAroundVertex& tav = m_topology->getTrianglesAroundVertex(t[j]); if (tav[0] == (sofa::core::topology::BaseMeshTopology::TriangleID)i) f |= (FLAG_P1 << j); } - const sofa::core::topology::BaseMeshTopology::EdgesInTriangle& e = _topology->getEdgesInTriangle(i); + const sofa::core::topology::BaseMeshTopology::EdgesInTriangle& e = m_topology->getEdgesInTriangle(i); for (unsigned int j=0; j<3; ++j) { - const sofa::core::topology::BaseMeshTopology::TrianglesAroundEdge& tae = _topology->getTrianglesAroundEdge(e[j]); + const sofa::core::topology::BaseMeshTopology::TrianglesAroundEdge& tae = m_topology->getTrianglesAroundEdge(e[j]); if (tae[0] == (sofa::core::topology::BaseMeshTopology::TriangleID)i) f |= (FLAG_E23 << j); if (tae.size() == 1) @@ -831,6 +488,76 @@ void TTriangleModel::computeBBox(const core::ExecParams* params, bool } +template +void TTriangleModel::draw(const core::visual::VisualParams* vparams ,int index) +{ + Element t(this,index); + + vparams->drawTool()->setPolygonMode(0,vparams->displayFlags().getShowWireFrame()); + vparams->drawTool()->setLightingEnabled(true); + vparams->drawTool()->drawTriangle( t.p1(), t.p2(), t.p3(), t.n() ); + vparams->drawTool()->setLightingEnabled(false); +} + + +template +void TTriangleModel::draw(const core::visual::VisualParams* vparams) +{ + if (vparams->displayFlags().getShowCollisionModels()) + { + // In case topology has changed but drawing is called before the updateFromTopology has been computed, just exit to avoid computation in drawing thread. + if (m_topology->getRevision() != m_topologyRevision) + return; + + if (d_bothSide.getValue() || vparams->displayFlags().getShowWireFrame()) + vparams->drawTool()->setPolygonMode(0,vparams->displayFlags().getShowWireFrame()); + else + { + vparams->drawTool()->setPolygonMode(2,true); + vparams->drawTool()->setPolygonMode(1,false); + } + + std::vector< defaulttype::Vector3 > points; + std::vector< defaulttype::Vec<3,int> > indices; + std::vector< defaulttype::Vector3 > normals; + int index=0; + for (int i=0; i(index,index+1,index+2)); + index+=3; + } + + vparams->drawTool()->setLightingEnabled(true); + vparams->drawTool()->drawTriangles(points, indices, normals, defaulttype::Vec<4,float>(getColor4f())); + vparams->drawTool()->setLightingEnabled(false); + vparams->drawTool()->setPolygonMode(0,false); + + + if (vparams->displayFlags().getShowNormals()) + { + std::vector< defaulttype::Vector3 > points; + for (int i=0; idrawTool()->drawLines(points, 1, defaulttype::Vec<4,float>(1,1,1,1)); + + } + } + if (getPrevious()!=NULL && vparams->displayFlags().getShowBoundingCollisionModels()) + getPrevious()->draw(vparams); +} + + + } // namespace collision } // namespace component diff --git a/applications/plugins/SofaMiscCollision/TriangleModelInRegularGrid.cpp b/applications/plugins/SofaMiscCollision/TriangleModelInRegularGrid.cpp index 53fb68af25e..636d1e2301d 100644 --- a/applications/plugins/SofaMiscCollision/TriangleModelInRegularGrid.cpp +++ b/applications/plugins/SofaMiscCollision/TriangleModelInRegularGrid.cpp @@ -71,17 +71,17 @@ void TriangleModelInRegularGrid::init() TriangleModel::init(); _topology = this->getContext()->getMeshTopology(); - mstate = dynamic_cast< core::behavior::MechanicalState* > (getContext()->getMechanicalState()); + m_mstate = dynamic_cast< core::behavior::MechanicalState* > (getContext()->getMechanicalState()); - if( !mstate) { serr << "TriangleModelInRegularGrid requires a Vec3 Mechanical Model" << sendl; return;} - if (!_topology) { serr << "TriangleModelInRegularGrid requires a BaseMeshTopology" << sendl; return;} + if( !m_mstate) { serr << "TriangleModelInRegularGrid requires a Vec3 Mechanical Model" << sendl; return;} + if (!m_topology) { serr << "TriangleModelInRegularGrid requires a BaseMeshTopology" << sendl; return;} // Test if _topology depend on an higher topology (to compute Bounding Tree faster) and get it TopologicalMapping* _topoMapping = NULL; vector topoVec; getContext()->get ( &topoVec, core::objectmodel::BaseContext::SearchRoot ); - _higher_topo = _topology; - _higher_mstate = mstate; + _higher_topo = m_topology; + _higher_mstate = m_mstate; bool found = true; while ( found ) { @@ -108,13 +108,13 @@ void TriangleModelInRegularGrid::computeBoundingTree ( int ) { CubeModel* cubeModel = createPrevious(); updateFromTopology(); - if ( needsUpdate && !cubeModel->empty() ) cubeModel->resize ( 0 ); - if ( !isMoving() && !cubeModel->empty() && !needsUpdate ) return; // No need to recompute BBox if immobile + if ( m_needsUpdate && !cubeModel->empty() ) cubeModel->resize ( 0 ); + if ( !isMoving() && !cubeModel->empty() && !m_needsUpdate ) return; // No need to recompute BBox if immobile - needsUpdate=false; + m_needsUpdate=false; Vector3 minElem, maxElem; const VecCoord& xHigh =_higher_mstate->read(core::ConstVecCoordId::position())->getValue(); - const VecCoord& x =mstate->read(core::ConstVecCoordId::position())->getValue(); + const VecCoord& x =m_mstate->read(core::ConstVecCoordId::position())->getValue(); // no hierarchy if ( empty() ) diff --git a/examples/Components/topology/TopologicalModifiers/AddingTrianglesProcess.scn b/examples/Components/topology/TopologicalModifiers/AddingTrianglesProcess.scn index ce3ea560ca1..91695fc773a 100644 --- a/examples/Components/topology/TopologicalModifiers/AddingTrianglesProcess.scn +++ b/examples/Components/topology/TopologicalModifiers/AddingTrianglesProcess.scn @@ -18,6 +18,7 @@ + diff --git a/examples/Components/topology/TopologicalModifiers/RemovingTrianglesProcess.scn b/examples/Components/topology/TopologicalModifiers/RemovingTrianglesProcess.scn index f5aaa5e9be0..71713b6004b 100644 --- a/examples/Components/topology/TopologicalModifiers/RemovingTrianglesProcess.scn +++ b/examples/Components/topology/TopologicalModifiers/RemovingTrianglesProcess.scn @@ -19,7 +19,7 @@ - + diff --git a/modules/SofaConstraint/LocalMinDistance.cpp b/modules/SofaConstraint/LocalMinDistance.cpp index aeaa0414325..508b41f8059 100644 --- a/modules/SofaConstraint/LocalMinDistance.cpp +++ b/modules/SofaConstraint/LocalMinDistance.cpp @@ -1429,7 +1429,7 @@ bool LocalMinDistance::testValidity(Line &l, const Vector3 &PQ) bool LocalMinDistance::testValidity(Triangle &t, const Vector3 &PQ) { TriangleModel *tM = t.getCollisionModel(); - bool bothSide_computation = tM->bothSide.getValue(); + bool bothSide_computation = tM->d_bothSide.getValue(); if (!filterIntersection.getValue() || bothSide_computation) return true; diff --git a/modules/SofaGeneralMeshCollision/TriangleOctreeModel.cpp b/modules/SofaGeneralMeshCollision/TriangleOctreeModel.cpp index b44bd889aae..c74e91df937 100644 --- a/modules/SofaGeneralMeshCollision/TriangleOctreeModel.cpp +++ b/modules/SofaGeneralMeshCollision/TriangleOctreeModel.cpp @@ -84,7 +84,7 @@ void TriangleOctreeModel::draw (const core::visual::VisualParams* vparams) void TriangleOctreeModel::computeBoundingTree(int maxDepth) { - const helper::vector& tri = *triangles; + const helper::vector& tri = *m_triangles; if(octreeRoot) { delete octreeRoot; @@ -95,16 +95,16 @@ void TriangleOctreeModel::computeBoundingTree(int maxDepth) updateFromTopology(); if (!isMoving() && !cubeModel->empty()) return; // No need to recompute BBox if immobile - int size2=mstate->getSize(); + int size2=m_mstate->getSize(); pNorms.resize(size2); for(int i=0; iread(core::ConstVecCoordId::position())->getValue()[0][0]; - maxElem[1]=minElem[1]=mstate->read(core::ConstVecCoordId::position())->getValue()[0][1]; - maxElem[2]=minElem[2]=mstate->read(core::ConstVecCoordId::position())->getValue()[0][2]; + maxElem[0]=minElem[0]=m_mstate->read(core::ConstVecCoordId::position())->getValue()[0][0]; + maxElem[1]=minElem[1]=m_mstate->read(core::ConstVecCoordId::position())->getValue()[0][1]; + maxElem[2]=minElem[2]=m_mstate->read(core::ConstVecCoordId::position())->getValue()[0][2]; cubeModel->resize(1); // size = number of triangles for (int i=1; i scene << " \n" << " \n" << " \n" + << " \n" << " <" << componentName << "/> \n" << " \n";