#ifndef _VTKCORGAN_v10B_ #define _VTKCORGAN_v10B_ #include "vtkBESSMat.h" #include "Macros.h" #include "vtkContact.h" #include "vtkEsquiPolyData.h" #include "vtkesquiT2MeshWin32Header.h" #include "vtkEsquiIdListCollection.h" #include "vtkEsquiLinkCollection.h" #include "vtkEsquiContactCollection.h" #include //! constants defining the different types of incisions (see Cut) //! V-shaped cut #define BESS_CUT_SHEARS 1 //! cut with the shape of a parallelogram #define BESS_CUT_SCALPEL 2 //! line shaped cut #define BESS_CUT_NEEDLE 3 //! 2D cut of surface #define BESS_CUT_SURFACE 4 //! totally cut into two halves #define BESS_CUT_TOTAL 8 //! positioning of clip (treatment almost like total cut) #define BESS_CLIP 16 //! constants defining the signification of the different return values of the function Cut #define BESS_CUT_FAIL 1 #define BESS_CUT_SUCCESS 0 //! Constants indicating how many additional nodes and elements there might be created by an //! incision to allow for reserving more memory for the different vectors, lists, and matrices //! than initially required, thus accelerating the incision algorithms #define BESS_RESERVE_NODES 12 // equivalent to single cut through three elements #define BESS_RESERVE_ELEMENTS 16 class vtkModeloDeformable; class vtkLink; class vtkEsquiLinkCollection; class vtkEsquiContactCollection; //! Abstract Base Class for deformable models class VTK_ESQUI_TMESH_EXPORT vtkOrgan: public vtkEsquiPolyData { public: vtkTypeRevisionMacro(vtkOrgan, vtkEsquiPolyData); const char *GetClassName() {return "vtkOrgan";} //virtual void PrintSelf(ostream &os, vtkIndent indent); //! Assign a id to Deformable model void SetModelId(int id); //! Returns the collision model of deformable model vtkModeloDeformable* GetCollisionModel(){ return _pDeformCModel; }; //! Delete the contacts virtual void DeleteContacts()=0; //! Initialize the collision model void InitCollisionModel(); //! Update the collision model void UpdateCollisionModel(); //! Convert a pointer to vtkContact into the organ's contact ID int ContactID( vtkContact* pContact ) { return m_lpContacts->IndexOf( pContact ); } //! Inquire whether the organ's geometry has changed and therefore has to be redrawn bool Deformed() { return m_bDeformed; } //! Return the organ's number of elements UINT Elements() { return m_uNEl; } //! Inquire organ's current number of nodes UINT GetNumNodes() const { return m_uNEl; } //! Obtain a specified node's current coordinates void GetVertex( int idPoly,int idVer,float* vertex ) const { int ind; ind = m_auNodePtr[idPoly*3+idVer]; vertex[0] = m_afCurrentCoord[ind*3]; vertex[1] = m_afCurrentCoord[ind*3+1]; vertex[2] = m_afCurrentCoord[ind*3+2]; } //! Obtain a specified node's current coordinates void GetVertex(int idVer,float* vertex ) const { vertex[0] = m_afCurrentCoord[idVer*3]; vertex[1] = m_afCurrentCoord[idVer*3+1]; vertex[2] = m_afCurrentCoord[idVer*3+2]; } //! Obtain the collision coordinates void GetCollisionCoord(int id,float* vertex ) const { vertex[0] = m_afColisionCoord[id*3]; vertex[1] = m_afColisionCoord[id*3+1]; vertex[2] = m_afColisionCoord[id*3+2]; } //! Returns the list of moved elements after last iteration int* GetMovedElements(int &numElements) { numElements = m_nElementosMovidos; return m_piElementosMovidos; } //! Returns the list of moved nodes after last iteration int* GetMovedNodes(int &numNodes){ numNodes = m_nNodosMovidos; return m_piNodosMovidos; } //! Initialize mesh data void Inicializar(); //! Transform the global coordinates c_afCoord of a point on the surface of the element c_uEl /* Transform the global coordinates c_afCoord of a point on the surface of the element c_uEl or the formed of the three specified nodes in its respective current (i.e. possibly displaced) state into local coordinates w.r.t. this element returns true if point lies within element, false otherwise, setting the local coordinates to {1/3.,1/3.,1/3.} */ bool MakeCoordLocal( float afCoordinates[], const UINT uEl ) { return MakeCoordLocal( afCoordinates,m_auNodePtr[3*uEl],m_auNodePtr[3*uEl+1],m_auNodePtr[3*uEl+2] ); } //! Transform the global coordinates c_afCoord of a point on the surface of the element c_uEl /* Transform the global coordinates c_afCoord of a point on the surface of the element c_uEl or the formed of the three specified nodes in its respective current (i.e. possibly displaced) state into local coordinates w.r.t. this element returns true if point lies within element, false otherwise, setting the local coordinates to {1/3.,1/3.,1/3.} */ bool MakeCoordLocal( float afCoordinates[], const UINT uNode0, const UINT uNode1, const UINT uNode2 ); //! Set gravity parameters, where the direction must be 0, 1, or 2 according to x-, y-, and z- direction, and the orientation must have a value of +1 or -1 void SetGravityInfo( const char yDirection, const char cOrientation ) { m_yDirOfGravity = yDirection; m_cOrientOfGravity = cOrientation; } //! Set maximum cutting distance void SetMaxCutDistance( const double dDistance ) { m_fMaxCutDistance = dDistance; } //! Define scale factor void SetScale( const double dScale ) { m_dScale = dScale; }; //! Set distance between scissor tips void SetTipsDistance( const double dDistance ) { m_fTipsDistance = dDistance; } //! Regenerate VTK geometry after changes due deformations void UpdateGeometry(); //! Methods for report building bool CanBeClipped() const { return m_bCanBeClipped; } //! Methods for report building bool ContainFluid() const { return m_bContainFluid; } //! Methods for report building void ContainFluid(int bValue) { if (bValue==0) { m_bContainFluid= false; }else{ m_bContainFluid= true;} } //! Methods for report building void CanBeClipped(int bValue) { if (bValue == 0) { m_bCanBeClipped= false; } else { m_bCanBeClipped= true; } } //! Force factor is used in the stimate force process for haptics void SetForceFactor(float value){ m_fForceFactor=value; } //! Force factor is used in the stimate force process for haptics float GetForceFactor() const{ return m_fForceFactor; } void GetUV(int i,float* u,float* v); void SetUV(int i,float u,float v); //! List of links between organs vtkEsquiLinkCollection *m_lpLinks; //! bEngachable indicate if the organ is clipped void Enganchable(int bEnganchable){ if (bEnganchable == 0) { m_bEnganchable = false; m_bDesgarrable = false; } else { m_bEnganchable = true; m_bDesgarrable = true; } }; //! bEngachable indicate if the organ is clipped bool EsEnganchable(){ return m_bEnganchable;}; //***** v i r t u a l m e m b e r s //! Add a Contact to the list /* Add a new contact to the contact list m_lpContacts; depending on mechanical model, to be implemented in the derived classes, which both have to call this funtion for tracing the contact, and have to call pContact->ExtraInit(...), if the contact's initial coord- inates are of interest or the constraint is shifted to one of the element's nodes */ virtual void AddContact( vtkContact* pC ) { m_lpContacts->Append( pC ); }; //! Add a new link to the link list m_lpLinks virtual void AddLink( vtkLink* pLk ) { m_lpLinks->Append( pLk ); } //! Inform the organ that a contact has been lost, i.e. remove it from the contact list (must be called by derived classes); virtual void ContactLost( vtkContact* pC) { m_lpContacts->DeleteNode(m_lpContacts->Find(pC)); } //! Remove a broken link virtual void RemoveLink( vtkLink* pLk ) { m_lpLinks->DeleteNode( m_lpLinks->Find( pLk ) ); } //! Totally remove the constraints marked for their removal virtual void RemoveRemovedConstraints() {} //! /* Este metodo obtiene los nodos implicados en un pinzamiento total y los almacena en una estructura del tipo PinzaTotal y los añade a la lista de pinzas (el primer elemento está apuntado por m_pPrimPinza solo la T2Mesh lo utiliza, sobreescribiendolo */ virtual int TotalCapture(unsigned uElementoComienzo, float *ptoElementoComienzo, float *pfVector) { return -1;} virtual int PartialCapture(const unsigned uElementoComienzo, float *ptoElementoComienzo, const unsigned uElementoFinal, float *ptoElementoFinal, float *pfVector) { return -1;} virtual bool DeformWithoutContacts(){ return false;}; //***** p u r e l y v i r t u a l m e m b e r s //! Cauterize organ at specified element //BTX virtual void Cauterize( const UINT uElement ) = NULL; //ETX //! Cut the organ with a tool of a certain type (scissors, scalpel, needle, ...) /* Cut the organ with a tool of a certain type (scissors, scalpel, needle, ...) between a starting and a final point on the organ's surface given by the respective elements within which they lie and their local coordinates w.r.t. this element; type examples: BESS_CUT_SHEARS: Cut between starting and final point; the additional vector is interpreted as the global coordinates of the final and common position of the scissor tips and serves to define both the cutting plane and edges, which will lie "above" this third point BESS_CUT_SCALPEL: Cut between starting and final point; the additional vector is interpreted as the global coordinates of a point "beyond" the starting point (i.e. in the organ's interior), and the cut will have the form of a parallelogram defined by the three points BESS_CUT_NEEDLE: "cut" or intrusion of a needle into the organ from a certain starting point (final point not needed); the additional vector is interpreted as the global coordinates of the final position of the needle's tip BESS_CUT_TOTAL: totally cut the organ into two halves, where the cutting plane is defined by the starting point (final point not needed) and the additional vector which is interpreted as the plane's unit normal */ //BTX virtual int Cut( const char cIncisionType, const UINT uStartElement, float* pfStartPointLocalCoord, const UINT uFinalElement, float* pfFinalPointLocalCoord, float* pfVector ) = NULL; //! Compute the current state of deformation. /* Compute the current state of deformation on behalf of the current positions of the tool points in contact with the organ (m_lpContacts[]->GetCoordX/Y/Z()) and update accordingly both the organ's nodal coordinates (m_vfCurrentCoord) and the tool points' force feedbacks (m_lpContacts[]->ForceUpdate(...)/TractionUpdate(...)); in case a contact is lost, calls ReleaseContact(...) to remove it from the contact list; merely virtual, i.e. has to be implemented by derived classes */ virtual void Deform(int iteracion) = NULL; //! Prepare simulation. It has to be implemented by derived classes virtual void PrepareSimulation() = NULL; //ETX // clip an organ; the parameters are the same as for BESS_CUT_TOTAL, with the last parameter // being a pointer to the object containing all the information needed for clip representation //virtual void PutClip( const UINT uStartElement, // float* pfStartPontLocalCoord, // float* pfFinPontLocalCoord, // float* pfVector, // vtkClip* pClip ) = NULL; //! Returns the number of needed iterations to obtain a stable deformable mesh virtual int GetNumIter(){ return 1;}; //***** p r o t e c t e d m e m b e r s protected: //! Output an error message and throw an exception void Error( const char *pcErrorMsg ) { throw; } //! Load boundary conditions, must be called after AddBoundaryConditions void LoadBoundaryConditions(); //! Release a contact by deleting it (indirectly, via the destructor //! of vtkContact, this also informs the involved tool and removes the contact from the contact list) void ReleaseContact( const vtkContact* pC ) { delete pC; } //! Release a contact by deleting it (indirectly, via the destructor //! of vtkContact, this also informs the involved tool and removes the contact from the contact list) void ReleaseContact( const int nC ) { m_lpContacts->Item( nC )->Delete() ; } //! Id for the geometric model int m_id; //! Collision model vtkModeloDeformable* _pDeformCModel; float m_fMaxX; float m_fMaxY; float m_fMaxZ; float m_vCenter[3]; int m_uNNodes; int m_uNEl; int m_uNColisiones; //! Texture coordinates float* m_afTextureCoord; float* m_afUV; //! Mesh for collisions float* m_afColisionCoord; float* m_afColisionCoordAnt; //! List of nodes corresponding to each element int* m_auNodePtr; //! Scale factor [mm/geometric unit] double m_dScale; //! Direction (0/1/2 for x/y/z) and orientation of gravity (+/- 1) char m_yDirOfGravity; char m_cOrientOfGravity; //! List of contacts organ is exposed to vtkEsquiContactCollection *m_lpContacts; //! Lists of nodes fixed in each of the three basic directions vtkEsquiIdListCollection *m_aluFixedNodes; //! Array with flags to indicate if the corresponding nodes are fixed in x-, y-, or z-direction //! (bits 0,1,2 set, respectively) //BTX vtkBESSArray m_acFixed; //ETX // flags indicating if nodal coordinates or even number of nodes has changed bool m_bDeformed; bool m_bNewVertices; //! Distances between start and end point of an incision and between scissors' tips double m_fMaxCutDistance; double m_fTipsDistance; //! For report building purpouses bool m_bCanBeClipped; bool m_bContainFluid; //! Parameter from Scene Gen, It's used to estimate force float m_fForceFactor; bool m_bEnganchable; //Parametros de desgarro bool m_bDesgarrable; float m_fUmbralDesgarro; //! Elements which has been moved (Needed for optimize of collision calc) int m_nElementosMovidos; int *m_piElementosMovidos; //! Nodes which has been moved (Needed for optimize of collision calc) //(Necesario para la obtimización en el cálculo de colisiones) int m_nNodosMovidos; int *m_piNodosMovidos; protected: //! Constructor por defecto vtkOrgan(); //! Destructor ~vtkOrgan(); private: vtkOrgan(const vtkOrgan &); void operator=(const vtkOrgan &); public: //! Adds a Boundary condition void AddBoundaryCondition(vtkIdType valorX, vtkIdType valorY, vtkIdType valorZ); }; ///////////////////////////////////////////////////////////////////////////// #endif