/* -------------------- Program: ESQUI Info and Bugs: {marf,rsantana}@ctm.ulpgc.es ------------------------------------------- Copyright (c) 2006, Center for Technology in Medicine, University of Las Palmas de Gran Canaria (Canary Islands, Spain). All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the Creative Commons' "by-attribution" license (http://creativecommons.org/licenses/by/2.5). Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================*/ #ifndef _CMALLAT2 #define _CMALLAT2 #include "vtkTiposT2.h" #include "vtkOrgan.h" #include "Macros.h" #include "vtkesquiT2MeshWin32Header.h" class vtkCara; //! Implementacion del modelo biomecánico T2-MESH /*! Esta clase implementa a una malla de tipo T2-mesh, estando esta formada por un vector de caras (el cual a su vez hace uso de la clase vtkCara), cuyos componentes son punteros a la lista de vertices. Los vertices deben ordenarse en sentido antihorario para que la representacion sombreada de buenos resultados, y ademas el ultimo de ellos coincide con el primero, cosa que viene bien de cara al calculo de la malla triangular dual y en el dibujado de la malla. // Ademas, esta clase contiene la malla triangular dual de la malla T2, ya que por el momento y hasta que no se amplie la implementacion, la lectura y escritura desde y a fichero se realiza solo con mallas triangulares. \sa vtkOrgan, vtkEsquiPolyData */ class VTK_ESQUI_TMESH_EXPORT vtkMallaT2: public vtkOrgan { //Clase que implementa una malla T2 //BTX //! clase que permite almacenar la informacion importante de la T2-Mesh //! para poder restaurar esta en caso de fallo friend class vtkDatosT2Mesh; //ETX public: static vtkMallaT2 *New(); vtkTypeRevisionMacro(vtkMallaT2,vtkOrgan); const char *GetClassName() {return "vtkMallaT2";} void PrintSelf(ostream &os, vtkIndent indent); /*****************************************************************/ //BTX //! Numero de puntos de la T2 int m_nNumPtosT2; //! Tipo de los puntos de la T2 int* m_pnTipoPunto; //! Estado de los puntos de la T2: seleccionado o no int* m_pnEstadoPunto; //! Marca el tipo de conexiones del nodo T2 (fantasma o real) INT3* m_panTipoConect; //! Puntos que forman la T2 Punto* m_pPuntosT2; //! Sera la textura asociada a cada vertice de la malla T2 Punto* m_pTexturaT2; //! Posicion de los puntos de la T2 en la iteracion anterior Punto* m_pPtosAntT2; int m_nNumGrapas; //! Estabilidad de los nodos bool* m_pbInestable; //ETX //! Indica si una cara esta siendo tocada por un dispositivo bool Tocado(int nCara); //! Indica si una nCara esta siendo pinzada con un pinzamiento total por parte de un dispositivo bool Pinzado(int nCara); //! Calcula la fuerza interna /* Este metodo permite calcular el desplazamiento para un nodo segun las tensiones de los muelles que lo unen con otros tres nodos */ void CalcularFuerzaInterna(int nIndPto,float fCompensacion); //! Calcula la fuerza interna libre /* Este metodo permite calcular el desplazamiento para un nodo segun las tensiones de los muelles que lo unen con otros tres nodos */ void CalcularFuerzaInternaLibre(int nIndPto,float fCompensacion); //! Calcula la posicion de los nodos /* Permite calcular la posición de los nodos unidos a otros nodos a través de links */ void CalculaPosLinks(); //! Permite calcular la posición de los nodos que han sido pinzados con un pizado total void CalculaPosPinzaTotal(); //! Crea la malla simple tipo 2 void PrepareSimulation(); //! Agnade un nuevo punto de contacto a la malla void AddContact( vtkContact* c_pContact ); //! Calcula numero de iteraciones en funcion de la deformacion indicada void Deform(int iteracion); //! Realiza el corte provocado por un dispositivo int Cut(const char tipocorte, const unsigned uElementoComienzo, float *ptoElementoComienzo, const unsigned uElementoFinal, float *ptoElementoFinal, float *pfVector); //! Cauteriza el Organo void Cauterize(const unsigned uElemento); //! Elimina un contacto de la lista de contactos void ContactLost( vtkContact* c_pContact ); //! Elimina todos los contactos void DeleteContacts(){ //Norberto while (m_lpContacts->GetFirst()!=NULL){ ContactLost (m_lpContacts->GetFirst()); } } //! Obtiene los nodos implicados en un pinzamiento total /* 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 esta apuntado por m_pPrimPinza) */ int TotalCapture(unsigned uElementoComienzo, float *ptoElementoComienzo, float *pfVector); //! Devuelve el numero de iteraciones que ha de realizar la T2-MEsh int GetNumIter(){ return m_nNumIter;}; int PartialCapture(const unsigned uElementoComienzo, float *ptoElementoComienzo, const unsigned uElementoFinal, float *ptoElementoFinal, float *pfVector); void RemoveRemovedConstraints(); //! Set Alpha parameter void SetAlphaParameter(float valor); //! Set Gamma parameter void SetGammaParameter(float valor); //! Set Ommega parameter void SetOmmegaParameter(float valor); protected: //! Constructor por defecto vtkMallaT2(); //! Destructor de la malla ~vtkMallaT2(); int m_nNumCaras; //! Estado de los muelles que unen cada punto en estado de reposo PUNTO3* m_paMuelles; //! Esta copia es necesaria en el proceso de corte total PUNTO3* m_paCopiaMuelles; //! Caras que forman la T2 //vtkCara* m_pCaras; vtkEsquiCaraCollection* m_pCaras; //! Usados para restablecer la malla original T2 Punto* m_pPtosOrigT2; //! Normales de la T2 Punto* m_pNormales; //! Conectividades de los puntos que forman la malla T2 INT3* m_panConect; //! Copia de las conexiones, necesario para el corte total INT3* m_panCopiaConect; //! Caras adyacentes a cada punto de la T2 INT3* m_panCarasAdy; //! Vector que marca la dirección de la gravedad en la escena Punto m_ptoDirGrav; //! Variables de la triangulacion. int m_nNumPtosTr; //! Variables de la triangulacion. int m_nNumTriang; //! Los puntos con los que se trabaje. Punto* m_pPtosTr; //! Triangulos que forman la triangulacion INT3* m_panTriangulos; //! Sirve para mantener coherencia con la lista de vertices de vtkOrgan //! \sa vtkOrgan int* m_pnCarasVacias; //! Sirve para mantener coherencia con la lista de vertices de vtkOrgan //! \sa vtkOrgan int* m_pnVtcesSueltos; int m_nNumContactos; vtkContacto* m_pContactoPrim; vtkContacto* m_pContactoUlt; int m_nNumIter; float m_fGravedad; //! Mide la "unidad" de corte, sirve para fijar la abertura del corte double m_fCutStep; //! Opciones para deformar la malla OpDeformacion m_OpcDeform; //! Indica si la T2 existe o no bool m_bHayMalla; //! Indica si hay un nuevo pinzamiento bool m_bNuevaPinza; //! Indica si se ha calculado una deformacion sin contactos bool m_bDeformSC; //! Determina la tension de los muelles /* Este atributo se usa para determinar, de forma dinamica, (durante el calculo de las fuerzas de deformacion que muelle esta excesivamente tensado y, por tanto, debería ser cortado */ //Este atributo se usa para determinar, de forma dinámica, (durante el cálculo de las fuerzas //de deformación) qué muelle está excesivamente tensado y, por tanto, debería ser cortado int m_nCaraCorte; float m_fMaxDist; //! Busca el vértice más cercano de entre los reales de la cara de contacto int BuscaContacto(int nTriangulo, Punto &ptoContacto, Punto &ptoVtceContacto); //! Devuelve el contacto de ataque /* devuelve "true" si el contacto de ataque es el positivo de la cara devuelve "false" si el contacto de ataque es el negatibo de la cara */ bool LadoContacto(int nTriangulo, Punto &ptoPosicion); //! Obtiene la triangulacion dual a la malla simple tipo 2 actual void ObtainTriangulation(); //! Reobtiene la triangulacion dual a la malla simple tipo 2 actual void ReObtainTriangulation(); //! Calcula la fuerza que se opone a la deformacion causada por las herramientas void ColisionForce(); //! Obtiene las caras adyacentes al vertice nVertice int Adyacentes(int nVertice,INT3 anResul) const; //! Encuentra el triángulo que comparte Vtce1 y Vtce2 con el triángulo tri int Vecino(int nTri, int nVtce1, int nVtce2) const; //! Calcula la interseccion de la arista de la cara con el plano definido por normplano y D Punto Intersecta(int nCara, int nArista, Punto &ptoNormPlano, float fD); //! Calcula la interseccion de la arista de la cara con el plano definido por normplano y D Punto Intersecta(Punto &ptoIni, Punto &ptoFin, Punto &ptoNormPlano, float fD); //! Mira si el punto intersección se encuentra dentro o en un extremo o en la arista de la cara int TipoNodo(int nCara, int nArista, Punto &ptoInter); //!Determina si el punto p esta dentro del triangulo /* Determina si el punto p esta dentro del triangulo definido por (t1, t2, t3) Si esta dentro, en ptoLocCoord devuelve las correspondientes coordenadas locales */ bool EstaenTriangulo(Punto &pto, Punto &ptoTri0, Punto &ptoTri1, Punto &ptoTri2, Punto &ptoLocCoor); //! Determina si el punto p está dentro del triángulo definido por (t1, t2, t3) bool EstaenTriangulo(Punto &pto, Punto &ptoTri0, Punto &ptoTri1, Punto &ptoTri2); //! Busca el corte a izquierdas o derechas /* Busca el corte a izquierdas o derechas (segun flgDir) de la cara actual (caraactual) Devuelve el punto de corte (pizq), la arista que corta (arista) y el tipo de corte (tipo) */ void CalculaInterseccion(int nCaraActual, Punto &ptoNormPlano, float fD, Punto &ptoIter, int &nArista, int &nTipoConect,int flgDir); //! Reequilibra una Interseccion que coincide con el nodo de una cara para que no coincida (dado que dara lugar a una cara degenerada) void ReequilibraInterseccion(int nCaraActual, int nArista, Punto &ptoInter); //! Obtiene la cara que esta en contacto con la cara actual a traves de arista int ObtieneSiguienteCara(int nCaraActual, int nArista); //! Comprueba que nCaraSig se puede alcanzar desde nCaraAct devolviendo la arista de nCaraSig compartida. bool SiguienteCaraArista(int nCaraAct,int nCaraSig,int* nArista); //! Devuelve el tipo de cara caraactual. int ObieneTipoCara(int nCaraActual); //! Crea las conexiones inicial, a izquierdas y a derechas segun el flag que se le pase como ultimo parametro void CreaConexion(vtkCamino *pCaminoAct, int &nNodoDer, int &nNodoIzq, Punto *pNuevosNodos, Punto *pNuevaTextura, INT3 *pnConexiones, int &nNumAnadidos, INT3 *pnTipoConect, PUNTO3 *pMuelleso, int flgDir, bool final = false, bool dirfinal = false); //! Crea la ultima conexion que enlaza el primer nodo con el ultimo en un corte total de superficie continua void CreaConexionFinal(vtkCamino* pIntersecciones,int nNodoDerIni, int nNodoIzqIni, int nNodoDer, int nNodoIzq, int nNumAnadidos,INT3 *pnConexiones, PUNTO3 *pMuelleso); //! Este procedimiento libera toda la memoria eliminando la informacion actual sobre la malla void DestruyeMallaT2(); //! Realiza una copia de los muelles, copia necesaria para luego los cortes, sobre todo para el corte total void CopiaEstadoMuelles(); //! Calcula el muelle que atraviesa una cara y que es generado durante el corte. Punto CalculaMuelle(vtkCamino* pIntersecciones, int nIndFin, int nIndIni, int nNumNodos); private: vtkMallaT2(const vtkMallaT2 &); void operator =(const vtkMallaT2 &); }; #endif