diff --git a/Common/VertexArray.cpp b/Common/VertexArray.cpp index 570255712b005d107e047b8469a5b3aef64f428d..3a42d4ab1a83d17e33d983786cfde868cdbbe8c4 100644 --- a/Common/VertexArray.cpp +++ b/Common/VertexArray.cpp @@ -1,4 +1,4 @@ -// $Id: VertexArray.cpp,v 1.4 2005-01-01 19:35:27 geuzaine Exp $ +// $Id: VertexArray.cpp,v 1.5 2005-05-21 01:10:46 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -27,8 +27,8 @@ VertexArray::VertexArray(int numNodesPerElement, int numElements) { type = numNodesPerElement; - if(type != 3 && type != 4){ - Msg(GERROR, "Vertex arrays should only contain triangles or quadrangles"); + if(type != 2 && type != 3 && type != 4){ + Msg(GERROR, "Vertex arrays should only contain lines, triangles or quadrangles"); type = 3; } num = fill = 0; @@ -66,6 +66,21 @@ void VertexArray::add(float x, float y, float z, List_Add(colors, &a); } +void VertexArray::add(float x, float y, float z, unsigned int col) +{ + unsigned char r = UNPACK_RED(col); + unsigned char g = UNPACK_GREEN(col); + unsigned char b = UNPACK_BLUE(col); + unsigned char a = UNPACK_ALPHA(col); + List_Add(vertices, &x); + List_Add(vertices, &y); + List_Add(vertices, &z); + List_Add(colors, &r); + List_Add(colors, &g); + List_Add(colors, &b); + List_Add(colors, &a); +} + static double theeye[3]; int compareTriEye(const void *a, const void *b) diff --git a/Common/VertexArray.h b/Common/VertexArray.h index c2509e84764868cee364b28a04a604a99bcaa10a..2d31f67ed3b4643caecbd96382c9bffd70f8e310 100644 --- a/Common/VertexArray.h +++ b/Common/VertexArray.h @@ -30,6 +30,7 @@ class VertexArray{ ~VertexArray(); void add(float x, float y, float z, float n0, float n1, float n2, unsigned int col); + void add(float x, float y, float z, unsigned int col); void sort(double eye[3]); }; diff --git a/Graphics/Draw.h b/Graphics/Draw.h index 5b6790c953a70716ff382ae75320219d99426d5e..b21a6f299225ce35f22fac0d5dfc2ca97765ad72 100644 --- a/Graphics/Draw.h +++ b/Graphics/Draw.h @@ -100,7 +100,7 @@ void Draw_Mesh_Tetrahedron(void *a, void *b); void Draw_Mesh_Hexahedron(void *a, void *b); void Draw_Mesh_Prism(void *a, void *b); void Draw_Mesh_Pyramid(void *a, void *b); -void Draw_Mesh_Array(VertexArray *va, int faces, int edges); +void Draw_Mesh_Array(VertexArray *va, int faces=0, int edges=0); #define ARGS Post_View *View, int preproNormals, \ double ValMin, double ValMax, \ diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp index 1cf9385bc886c520155d0208c499007428c266f8..abafe8d1c8d49025e1f3a571dcf1ff602da498f2 100644 --- a/Graphics/Mesh.cpp +++ b/Graphics/Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Mesh.cpp,v 1.125 2005-03-15 15:43:31 geuzaine Exp $ +// $Id: Mesh.cpp,v 1.126 2005-05-21 01:10:47 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -47,6 +47,7 @@ extern int quadfaces_pyramid[1][4]; static DrawingColor theColor; static int thePhysical = 0; +static Curve *theCurve = NULL; static Surface *theSurface = NULL; static Volume *theVolume = NULL; @@ -427,11 +428,37 @@ void Draw_Mesh_Curve(void *a, void *b) return; if(!(c->Visible & VIS_MESH)) return; + + theCurve = c; theColor = c->Color; thePhysical = getFirstPhysical(MSH_PHYSICAL_LINE, c->Num); - Tree_Action(c->Simplexes, Draw_Mesh_Line); - Tree_Action(c->SimplexesBase, Draw_Mesh_Line); + if(CTX.mesh.vertex_arrays){ + if(CTX.mesh.changed){ + Msg(DEBUG, "regenerate curve mesh vertex array"); + if(c->LinVertexArray) delete c->LinVertexArray; + c->LinVertexArray = new VertexArray(2, Tree_Nbr(c->Simplexes) + + Tree_Nbr(c->SimplexesBase)); + c->LinVertexArray->fill = 1; + Tree_Action(c->Simplexes, Draw_Mesh_Line); + Tree_Action(c->SimplexesBase, Draw_Mesh_Line); + if(c->LinVertexArray){ + Msg(DEBUG, "%d segments in curve vertex array", c->LinVertexArray->num); + c->LinVertexArray->fill = 0; + } + } + if(c->LinVertexArray) + Draw_Mesh_Array(c->LinVertexArray); + } + + if(!c->LinVertexArray || CTX.mesh.lines_num || + CTX.mesh.points_per_element || CTX.mesh.tangents){ + Msg(DEBUG, "classic line data path"); + Tree_Action(c->Simplexes, Draw_Mesh_Line); + Tree_Action(c->SimplexesBase, Draw_Mesh_Line); + } + + theCurve = NULL; } void Draw_Mesh_Point(int num, double x, double y, double z, int degree, int visible) @@ -527,26 +554,41 @@ void Draw_Mesh_Line(void *a, void *b) s->VSUP[0]->Degree, s->VSUP[0]->Visible); } + unsigned int col; if(theColor.type) - glColor4ubv((GLubyte *) & theColor.mesh); + col = theColor.mesh; else if(CTX.mesh.color_carousel == 1) - glColor4ubv((GLubyte *) & CTX.color.mesh.carousel[abs(s->iEnt % 10)]); + col = CTX.color.mesh.carousel[abs(s->iEnt % 10)]; else if(CTX.mesh.color_carousel == 2) - glColor4ubv((GLubyte *) & CTX.color.mesh.carousel[abs(thePhysical % 10)]); + col = CTX.color.mesh.carousel[abs(thePhysical % 10)]; else if(CTX.mesh.color_carousel == 3) - glColor4ubv((GLubyte *) & CTX.color.mesh.carousel[abs(s->iPart % 10)]); + col = CTX.color.mesh.carousel[abs(s->iPart % 10)]; else - glColor4ubv((GLubyte *) & CTX.color.mesh.line); - - if(CTX.mesh.lines) { - glBegin(GL_LINE_STRIP); - for(int i = 0; i < N; i++){ - glVertex3d(X[i], Y[i], Z[i]); + col = CTX.color.mesh.line; + + if(theCurve && theCurve->LinVertexArray && theCurve->LinVertexArray->fill){ + theCurve->LinVertexArray->add(X[0], Y[0], Z[0], col); + theCurve->LinVertexArray->add(X[1], Y[1], Z[1], col); + theCurve->LinVertexArray->num++; + if(N == 3){ + theCurve->LinVertexArray->add(X[1], Y[1], Z[1], col); + theCurve->LinVertexArray->add(X[2], Y[2], Z[2], col); + theCurve->LinVertexArray->num++; + } + } + else{ + if(CTX.mesh.lines) { + glColor4ubv((GLubyte *) & col); + glBegin(GL_LINE_STRIP); + for(int i = 0; i < N; i++){ + glVertex3d(X[i], Y[i], Z[i]); + } + glEnd(); } - glEnd(); } if(CTX.mesh.lines_num) { + glColor4ubv((GLubyte *) & col); sprintf(Num, "%d", s->Num); double offset = 0.3 * (CTX.mesh.line_width + CTX.gl_fontsize) * CTX.pixel_equiv_x; glRasterPos3d(Xc + offset / CTX.s[0], @@ -696,33 +738,38 @@ void Draw_Mesh_Array(VertexArray *va, int faces, int edges) return; glVertexPointer(3, GL_FLOAT, 0, va->vertices->array); - glNormalPointer(GL_FLOAT, 0, va->normals->array); glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->colors->array); + glNormalPointer(GL_FLOAT, 0, va->normals->array); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - if(faces){ - if(CTX.mesh.light) - glEnable(GL_LIGHTING); - else - glDisableClientState(GL_NORMAL_ARRAY); - if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL); - glDrawArrays((va->type == 3) ? GL_TRIANGLES : GL_QUADS, 0, va->type * va->num); - glDisable(GL_POLYGON_OFFSET_FILL); - glDisable(GL_LIGHTING); + if(va->type == 2){ + glDisableClientState(GL_NORMAL_ARRAY); + glDrawArrays(GL_LINES, 0, va->type * va->num); } - - if(edges){ + else{ if(faces){ - glDisableClientState(GL_COLOR_ARRAY); - glColor4ubv((GLubyte *) & CTX.color.mesh.line); + if(CTX.mesh.light) + glEnable(GL_LIGHTING); + else + glDisableClientState(GL_NORMAL_ARRAY); + if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL); + glDrawArrays((va->type == 3) ? GL_TRIANGLES : GL_QUADS, 0, va->type * va->num); + glDisable(GL_POLYGON_OFFSET_FILL); + glDisable(GL_LIGHTING); + } + if(edges){ + if(faces){ + glDisableClientState(GL_COLOR_ARRAY); + glColor4ubv((GLubyte *) & CTX.color.mesh.line); + } + glDisableClientState(GL_NORMAL_ARRAY); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glDrawArrays((va->type == 3) ? GL_TRIANGLES : GL_QUADS, 0, va->type * va->num); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } - glDisableClientState(GL_NORMAL_ARRAY); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glDrawArrays((va->type == 3) ? GL_TRIANGLES : GL_QUADS, 0, va->type * va->num); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } glDisableClientState(GL_VERTEX_ARRAY); diff --git a/Mesh/Create.cpp b/Mesh/Create.cpp index e30bce3e7f0b0c51e6b85958ef3ad4b9071d53e7..cf017ea875602031047d8173f0e8554f5d6f960b 100644 --- a/Mesh/Create.cpp +++ b/Mesh/Create.cpp @@ -1,4 +1,4 @@ -// $Id: Create.cpp,v 1.73 2005-05-15 01:44:26 geuzaine Exp $ +// $Id: Create.cpp,v 1.74 2005-05-21 01:10:47 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -510,10 +510,6 @@ void End_Surface(Surface * s, int reset_orientations) Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste, List_T * Knots, int p1, int p2, double u1, double u2) { - Curve *pC; - Vertex *v; - int i, j, iPnt; - double d; double matcr[4][4] = { {-0.5, 1.5, -1.5, 0.5}, {1.0, -2.5, 2.0, -0.5}, {-0.5, 0.0, 0.5, 0.0}, @@ -527,12 +523,14 @@ Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste, {-3, 3.0, 0, 0.0}, {1, 0, 0, 0.0} }; - pC = (Curve *) Malloc(sizeof(Curve)); + Curve *pC = (Curve *) Malloc(sizeof(Curve)); pC->bds = 0; + pC->LinVertexArray = NULL; pC->Color.type = 0; pC->Visible = VIS_GEOM | VIS_MESH; pC->cp = NULL; pC->Vertices = List_Create(2, 20, sizeof(Vertex *)); + pC->VerticesTemp = NULL; pC->Extrude = NULL; pC->Typ = Typ; pC->Num = Num; @@ -544,24 +542,24 @@ Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste, pC->Circle.n[0] = 0.0; pC->Circle.n[1] = 0.0; pC->Circle.n[2] = 1.0; - for(i = 0; i < 4; i++) { + for(int i = 0; i < 4; i++) { pC->ipar[i] = 0; pC->dpar[i] = 0.0; } if(Typ == MSH_SEGM_SPLN) { - for(i = 0; i < 4; i++) - for(j = 0; j < 4; j++) + for(int i = 0; i < 4; i++) + for(int j = 0; j < 4; j++) pC->mat[i][j] = matcr[i][j]; } else if(Typ == MSH_SEGM_BSPLN) { - for(i = 0; i < 4; i++) - for(j = 0; j < 4; j++) + for(int i = 0; i < 4; i++) + for(int j = 0; j < 4; j++) pC->mat[i][j] = matbs[i][j] / 6.0; } else if(Typ == MSH_SEGM_BEZIER) { - for(i = 0; i < 4; i++) - for(j = 0; j < 4; j++) + for(int i = 0; i < 4; i++) + for(int j = 0; j < 4; j++) pC->mat[i][j] = matbez[i][j]; } @@ -575,7 +573,8 @@ Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste, List_Read(Knots, List_Nbr(Knots) - 1, &kmax); pC->ubeg = kmin; pC->uend = kmax; - for(i = 0; i < List_Nbr(Knots); i++) { + for(int i = 0; i < List_Nbr(Knots); i++) { + double d; List_Read(Knots, i, &d); pC->k[i] = (float)d; } @@ -585,8 +584,10 @@ Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste, if(Liste) { pC->Control_Points = List_Create(List_Nbr(Liste), 1, sizeof(Vertex *)); - for(j = 0; j < List_Nbr(Liste); j++) { + for(int j = 0; j < List_Nbr(Liste); j++) { + int iPnt; List_Read(Liste, j, &iPnt); + Vertex *v; if((v = FindPoint(iPnt, THEM))) List_Add(pC->Control_Points, &v); else{ @@ -606,6 +607,7 @@ Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste, List_Read(pC->Control_Points, List_Nbr(pC->Control_Points) - 1, &pC->end); } else { + Vertex *v; if((v = FindPoint(p1, THEM))) { Msg(INFO, "Curve %d first control point %d ", pC->Num, v->Num); pC->beg = v; @@ -631,6 +633,8 @@ void Free_Curve(void *a, void *b) { Curve *pC = *(Curve **) a; if(pC) { + if(pC->LinVertexArray) + delete pC->LinVertexArray; List_Delete(pC->Vertices); Tree_Action(pC->Simplexes, Free_Simplex); Tree_Delete(pC->Simplexes); @@ -646,10 +650,7 @@ void Free_Curve(void *a, void *b) Surface *Create_Surface(int Num, int Typ) { - Surface *pS; - int i; - - pS = (Surface *) Malloc(sizeof(Surface)); + Surface *pS = (Surface *) Malloc(sizeof(Surface)); pS->bds = 0; pS->Color.type = 0; pS->Visible = VIS_GEOM | VIS_MESH; @@ -657,7 +658,7 @@ Surface *Create_Surface(int Num, int Typ) THEM->MaxSurfaceNum = IMAX(THEM->MaxSurfaceNum, Num); pS->Typ = Typ; pS->Method = LIBRE; - for(i = 0; i < 5; i++) + for(int i = 0; i < 5; i++) pS->ipar[i] = 0; pS->Recombine = 0; pS->RecombineAngle = 75; @@ -714,17 +715,14 @@ void Free_Surface(void *a, void *b) Volume *Create_Volume(int Num, int Typ) { - Volume *pV; - int i; - - pV = (Volume *) Malloc(sizeof(Volume)); + Volume *pV = (Volume *) Malloc(sizeof(Volume)); pV->Color.type = 0; pV->Visible = VIS_GEOM | VIS_MESH; pV->Num = Num; THEM->MaxVolumeNum = IMAX(THEM->MaxVolumeNum, Num); pV->Typ = Typ; pV->Method = LIBRE; - for(i = 0; i < 8; i++) + for(int i = 0; i < 8; i++) pV->ipar[i] = 0; pV->TrsfPoints = List_Create(6, 6, sizeof(Vertex *)); pV->Surfaces = List_Create(1, 2, sizeof(Surface *)); diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h index 54cbe81d3e313cc6fff0737f00cb8fa28e8ab2f2..027816b18a2d5517c6237a6e9b4f1ba9cefb5fe2 100644 --- a/Mesh/Mesh.h +++ b/Mesh/Mesh.h @@ -354,26 +354,28 @@ typedef struct{ }CircParam; typedef struct{ - int Num; - int Typ; - char Visible; - int Method; - int ipar[4]; - double dpar[4]; - double l; - double mat[4][4]; - Vertex *beg, *end; - double ubeg, uend; - List_T *Control_Points; - List_T *Vertices; - Tree_T *Simplexes, *SimplexesBase; - ExtrudeParams *Extrude; - float *k, *cp; - int degre; - CircParam Circle; - char functu[256], functv[256], functw[256]; - DrawingColor Color; - BDS_Mesh *bds; + int Num; + int Typ; + char Visible; + int Method; + int ipar[4]; + double dpar[4]; + double l; + double mat[4][4]; + Vertex *beg, *end; + double ubeg, uend; + List_T *Control_Points; + List_T *Vertices; + Tree_T *VerticesTemp; // a temp tree for fast vertex insertion + Tree_T *Simplexes, *SimplexesBase; + ExtrudeParams *Extrude; + float *k, *cp; + int degre; + CircParam Circle; + char functu[256], functv[256], functw[256]; + DrawingColor Color; + BDS_Mesh *bds; + VertexArray *LinVertexArray; }Curve; typedef struct{ diff --git a/Mesh/Read_Mesh.cpp b/Mesh/Read_Mesh.cpp index 2a07ac1b8f2539052bde4c6c1b3881304697b57e..ed16b303c2199af0c6f4126437694fff1183bacd 100644 --- a/Mesh/Read_Mesh.cpp +++ b/Mesh/Read_Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Read_Mesh.cpp,v 1.87 2005-05-15 01:44:26 geuzaine Exp $ +// $Id: Read_Mesh.cpp,v 1.88 2005-05-21 01:10:47 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -120,6 +120,21 @@ int getNbrNodes(int Type) } } +static Curve *theCurve = NULL; + +static void TransferVertex(void *a, void *b) +{ + List_Add(theCurve->Vertices, a); +} + +static void Transfer_VertexTree2List(void *a, void *b) +{ + theCurve = *(Curve**)a; + Tree_Action(theCurve->VerticesTemp, TransferVertex); + Tree_Delete(theCurve->VerticesTemp); + theCurve->VerticesTemp = NULL; +} + void Read_Mesh_MSH(Mesh * M, FILE * fp) { char String[256]; @@ -325,8 +340,16 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp) Free_SimplexBase(&simp, 0); } else{ + // This is dog slow when there is a large num of verts per curve: + // + // for(i = 0; i < Nbr_Nodes; i++) + // List_Insert(c->Vertices, &vertsp[i], fcmp_int); + // + // So we use a temp tree instead: + if(!c->VerticesTemp) + c->VerticesTemp = Tree_Create(sizeof(Vertex *), compareVertex); for(i = 0; i < Nbr_Nodes; i++) - List_Insert(c->Vertices, &vertsp[i], fcmp_int); + Tree_Insert(c->VerticesTemp, &vertsp[i]); } break; case TRI1: @@ -536,6 +559,9 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp) // re-sort the list according to these indices to allow direct // access through List_Pointer & co. List_Sort(M->Partitions, compareMeshPartitionIndex); + + // Transfer the vertices from temp trees into lists + Tree_Action(M->Curves, Transfer_VertexTree2List); } // Read mesh in VTK format diff --git a/doc/VERSIONS b/doc/VERSIONS index 7aa1b734513ddce0dc74697c65b9513e3e142b20..2801646f1f59584ae1057e094bdec4c2f58a3a75 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,11 +1,12 @@ -$Id: VERSIONS,v 1.326 2005-04-06 21:40:15 geuzaine Exp $ +$Id: VERSIONS,v 1.327 2005-05-21 01:10:48 geuzaine Exp $ New since 1.60: added support for second order (curved) elements in post-processor; new version (1.4) of post-processing file formats; new stippling options for 2D plots; removed limit on allowed number of files on command line; all "Combine" operations are now available in the parser; changed View.ArrowLocation into View.GlyphLocation; -optimized memory usage when loading many (>1000) views; +optimized memory usage when loading many (>1000) views; optimzed +loading and drawing of line meshes; New in 1.60: added support for discrete curves; new Window menu on Mac OS X; generalized all octree-based plugins (CutGrid, StreamLines,