Select Git revision
-
Giannis Nikiteas authored
The output vector array from C strings to Fortran strings was not properly initialised. Now each individual character is copied into the Fortran string.
Giannis Nikiteas authoredThe output vector array from C strings to Fortran strings was not properly initialised. Now each individual character is copied into the Fortran string.
Visibility.cpp 17.42 KiB
// $Id: Visibility.cpp,v 1.11 2005-01-01 19:35:27 geuzaine Exp $
//
// Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to <gmsh@geuz.org>.
#include "Gmsh.h"
#include "Geo.h"
#include "CAD.h"
#include "Mesh.h"
#include "Parser.h"
#include "Visibility.h"
extern Mesh *THEM;
static List_T *ElementaryEntities = NULL, *PhysicalEntities = NULL, *Partitions = NULL;
static Tree_T *VisibleThroughPhysical[4] = { NULL, NULL, NULL, NULL };
static List_T *NumxSymb = NULL;
static int Sort = 1;
int Entity::Num()
{
switch (type) {
case 1:
case 2:
case 3:
case 4:
return data.physical ? data.physical->Num : 0;
case 5:
return data.vertex ? data.vertex->Num : 0;
case 6:
return data.curve ? data.curve->Num : 0;
case 7:
return data.surface ? data.surface->Num : 0;
case 8:
return data.volume ? data.volume->Num : 0;
case 9:
return data.partition ? data.partition->Num : 0;
default:
return 0;
}
}
char *Entity::Type()
{
switch (type) {
case 1:
case 5:
return "Point";
case 2:
case 6:
return "Line";
case 3:
case 7:
return "Surface";
case 4:
case 8:
return "Volume";
case 9:
return "Partition";
default:
return "Unknown";
}
}
char *Entity::Name()
{
char *tmp = "";
return str ? str : tmp;
}
static char browserline[512];
char *Entity::BrowserLine()
{
if(type) {
sprintf(browserline, "\t%s\t%d\t%s", Type(), Num(), Name());
return browserline;
}
else
return Name();
}
int Entity::Visible()
{
switch (type) {
case 1:
case 2:
case 3:
case 4:
return data.physical ? data.physical->Visible : 0;
case 5:
return data.vertex ? data.vertex->Visible : 0;
case 6:
return data.curve ? data.curve->Visible : 0;
case 7:
return data.surface ? data.surface->Visible : 0;
case 8:
return data.volume ? data.volume->Visible : 0;
case 9:
return data.partition ? data.partition->Visible : 0;
default:
return 0;
}
}
void Entity::Visible(int mode)
{
Vertex *v;
Curve *c;
Surface *s;
Volume *V;
int i, j;
switch (type) {
case 1:
if(!data.physical)
break;
data.physical->Visible = mode;
for(i = 0; i < List_Nbr(data.physical->Entities); i++) {
List_Read(data.physical->Entities, i, &j);
if((v = FindPoint(j, THEM))) {
if(Tree_Search(VisibleThroughPhysical[0], &j)) {
v->Visible = v->Visible | mode;
}
else {
v->Visible = mode;
if(mode)
Tree_Add(VisibleThroughPhysical[0], &j);
}
}
}
break;
case 2:
if(!data.physical)
break;
data.physical->Visible = mode;
for(i = 0; i < List_Nbr(data.physical->Entities); i++) {
List_Read(data.physical->Entities, i, &j);
if((c = FindCurve(abs(j), THEM))) {
if(Tree_Search(VisibleThroughPhysical[1], &j)) {
c->Visible = c->Visible | mode;
}
else {
c->Visible = mode;
if(mode)
Tree_Add(VisibleThroughPhysical[1], &j);
}
}
}
break;
case 3:
if(!data.physical)
break;
data.physical->Visible = mode;
for(i = 0; i < List_Nbr(data.physical->Entities); i++) {
List_Read(data.physical->Entities, i, &j);
if((s = FindSurface(abs(j), THEM))) {
if(Tree_Search(VisibleThroughPhysical[2], &j)) {
s->Visible = s->Visible | mode;
}
else {
s->Visible = mode;
if(mode)
Tree_Add(VisibleThroughPhysical[2], &j);
}
};
}
break;
case 4:
if(!data.physical)
break;
data.physical->Visible = mode;
for(i = 0; i < List_Nbr(data.physical->Entities); i++) {
List_Read(data.physical->Entities, i, &j);
if((V = FindVolume(abs(j), THEM))) {
if(Tree_Search(VisibleThroughPhysical[3], &j)) {
V->Visible = V->Visible | mode;
}
else {
V->Visible = mode;
if(mode)
Tree_Add(VisibleThroughPhysical[3], &j);
}
}
}
break;
case 5:
if(!data.vertex)
break;
data.vertex->Visible = mode;
break;
case 6:
if(!data.curve)
break;
data.curve->Visible = mode;
break;
case 7:
if(!data.surface)
break;
data.surface->Visible = mode;
break;
case 8:
if(!data.volume)
break;
data.volume->Visible = mode;
break;
case 9:
if(!data.partition)
break;
data.partition->Visible = mode;
break;
}
}
static void Recur(Curve * c, int mode)
{
int k;
Vertex *v;
for(k = 0; k < List_Nbr(c->Control_Points); k++) {
List_Read(c->Control_Points, k, &v);
v->Visible = v->Visible | mode;
}
}
static void Recur(Surface * s, int mode)
{
int k, l;
Vertex *v;
Curve *c;
for(k = 0; k < List_Nbr(s->Generatrices); k++) {
List_Read(s->Generatrices, k, &c);
if(c->Num < 0)
c = FindCurve(-c->Num, THEM);
if(c) {
c->Visible = c->Visible | mode;
for(l = 0; l < List_Nbr(c->Control_Points); l++) {
List_Read(c->Control_Points, l, &v);
v->Visible = v->Visible | mode;
}
}
}
}
static void Recur(Volume * V, int mode)
{
int k, l, m;
Vertex *v;
Curve *c;
Surface *s;
for(k = 0; k < List_Nbr(V->Surfaces); k++) {
List_Read(V->Surfaces, k, &s);
s->Visible = s->Visible | mode;
for(l = 0; l < List_Nbr(s->Generatrices); l++) {
List_Read(s->Generatrices, l, &c);
if(c->Num < 0)
c = FindCurve(-c->Num, THEM);
if(c) {
c->Visible = c->Visible | mode;
for(m = 0; m < List_Nbr(c->Control_Points); m++) {
List_Read(c->Control_Points, m, &v);
v->Visible = v->Visible | mode;
}
}
}
}
}
void Entity::RecurVisible()
{
int j, k, mode;
Curve *c;
Surface *s;
Volume *V;
mode = Visible();
if(mode) {
switch (type) {
case 1:
break;
case 2:
if(!data.physical)
break;
for(j = 0; j < List_Nbr(data.physical->Entities); j++) {
List_Read(data.physical->Entities, j, &k);
if((c = FindCurve(abs(k), THEM)))
Recur(c, mode);
}
break;
case 3:
if(!data.physical)
break;
for(j = 0; j < List_Nbr(data.physical->Entities); j++) {
List_Read(data.physical->Entities, j, &k);
if((s = FindSurface(abs(k), THEM)))
Recur(s, mode);
}
break;
case 4:
if(!data.physical)
break;
for(j = 0; j < List_Nbr(data.physical->Entities); j++) {
List_Read(data.physical->Entities, j, &k);
if((V = FindVolume(abs(k), THEM)))
Recur(V, mode);
}
break;
case 5:
break;
case 6:
if(!data.curve)
break;
Recur(data.curve, mode);
break;
case 7:
if(!data.surface)
break;
Recur(data.surface, mode);
break;
case 8:
if(!data.volume)
break;
Recur(data.volume, mode);
break;
case 9:
break;
}
}
}
void SetVisibilitySort(int sort)
{
if(Sort == sort)
Sort = -sort;
else
Sort = sort;
}
static int CompareEntity(const void *a, const void *b)
{
Entity *p = (Entity *) a, *q = (Entity *) b;
switch (Sort) {
case 1:
return p->type - q->type;
case -1:
return q->type - p->type;
case 2:
return p->Num() - q->Num();
case -2:
return q->Num() - p->Num();
case 3:
return strcmp(p->Name(), q->Name());
case -3:
return strcmp(q->Name(), p->Name());
default:
return 0;
}
}
static int CompareNxS(const void *a, const void *b)
{
NxS *p = (NxS *) a, *q = (NxS *) b;
return p->n - q->n;
}
static char *GetString(int num)
{
NxS nxs, *pnxs;
nxs.n = num;
if((pnxs = (NxS *) List_PQuery(NumxSymb, &nxs, CompareNxS)))
return pnxs->s;
else
return NULL;
}
static void AddPhysical(void *a, void *b)
{
PhysicalGroup *p = *(PhysicalGroup **) a;
Entity e;
switch (p->Typ) {
case MSH_PHYSICAL_POINT:
e.type = 1;
break;
case MSH_PHYSICAL_LINE:
e.type = 2;
break;
case MSH_PHYSICAL_SURFACE:
e.type = 3;
break;
case MSH_PHYSICAL_VOLUME:
e.type = 4;
break;
}
e.data.physical = p;
e.str = GetString(p->Num);
List_Add(PhysicalEntities, &e);
}
static void AddPartition(void *a, void *b)
{
MeshPartition *p = *(MeshPartition **) a;
Entity e;
e.type = 9;
e.data.partition = p;
e.str = NULL;
List_Add(Partitions, &e);
}
static void AddVertex(void *a, void *b)
{
Vertex *v = *(Vertex **) a;
Entity e;
e.type = 5;
e.data.vertex = v;
e.str = GetString(v->Num);
List_Add(ElementaryEntities, &e);
}
static void AddCurve(void *a, void *b)
{
Curve *c = *(Curve **) a;
if(c->Num < 0)
return;
Entity e;
e.type = 6;
e.data.curve = c;
e.str = GetString(c->Num);
List_Add(ElementaryEntities, &e);
}
static void AddSurface(void *a, void *b)
{
Surface *s = *(Surface **) a;
Entity e;
e.type = 7;
e.data.surface = s;
e.str = GetString(s->Num);
List_Add(ElementaryEntities, &e);
}
static void AddVolume(void *a, void *b)
{
Volume *v = *(Volume **) a;
Entity e;
e.type = 8;
e.data.volume = v;
e.str = GetString(v->Num);
List_Add(ElementaryEntities, &e);
}
static void addInNumxSymb(void *a, void *b){
Symbol *s;
NxS nxs;
s = (Symbol *)a;
for(int j = 0; j < List_Nbr(s->val); j++) {
nxs.n = (int)(*(double *)List_Pointer(s->val, j));
nxs.s = s->Name;
List_Add(NumxSymb, &nxs);
}
}
List_T *GetVisibilityList(int type)
{
if(!ElementaryEntities)
ElementaryEntities = List_Create(100, 100, sizeof(Entity));
else
List_Reset(ElementaryEntities);
if(!PhysicalEntities)
PhysicalEntities = List_Create(100, 100, sizeof(Entity));
else
List_Reset(PhysicalEntities);
if(!Partitions)
Partitions = List_Create(100, 100, sizeof(Entity));
else
List_Reset(Partitions);
if(!NumxSymb)
NumxSymb = List_Create(100, 100, sizeof(NxS));
else
List_Reset(NumxSymb);
Tree_Action(Symbol_T, addInNumxSymb);
if(THEM){
List_Action(THEM->PhysicalGroups, AddPhysical);
List_Action(THEM->Partitions, AddPartition);
Tree_Action(THEM->Points, AddVertex);
Tree_Action(THEM->Curves, AddCurve);
Tree_Action(THEM->Surfaces, AddSurface);
Tree_Action(THEM->Volumes, AddVolume);
}
List_Sort(ElementaryEntities, CompareEntity);
List_Sort(PhysicalEntities, CompareEntity);
List_Sort(Partitions, CompareEntity);
switch (type) {
case ELEMENTARY:
return ElementaryEntities;
case PHYSICAL:
return PhysicalEntities;
case PARTITION:
default:
return Partitions;
}
}
void ClearVisibilityList(int type)
{
int i;
Entity *e;
List_T *list;
switch(type){
case ELEMENTARY : list = ElementaryEntities; break;
case PHYSICAL : list = PhysicalEntities; break;
case PARTITION : list = Partitions; break;
default: return;
}
for(i = 0; i < List_Nbr(list); i++) {
e = (Entity *) List_Pointer(list, i);
e->Visible(0);
}
}
void InitVisibilityThroughPhysical()
{
int i;
for(i = 0; i < 4; i++) {
if(VisibleThroughPhysical[i])
Tree_Delete(VisibleThroughPhysical[i]);
VisibleThroughPhysical[i] = Tree_Create(sizeof(int), fcmp_absint);
}
}
void SetVisibilityByNumber(int num, int type, int mode)
{
int i, found;
List_T *tmp;
Vertex vv, *v, **pv;
Curve *c;
Surface *s;
Volume *V;
Simplex SS, *S, **pS;
SimplexBase SSB, *SB, **pSB;
Quadrangle QQ, *Q, **pQ;
Hexahedron HH, *H, **pH;
Prism PP, *P, **pP;
Pyramid YY, *Y, **pY;
if(!THEM)
return;
switch (type) {
case 0: //node
vv.Num = num;
v = &vv;
if((pv = (Vertex **) Tree_PQuery(THEM->Vertices, &v)))
(*pv)->Visible = mode;
else
Msg(WARNING, "Unknown node %d (use '*' to hide/show all nodes)", num);
break;
case 1: //element
SS.Num = num; S = &SS;
SSB.Num = num; SB = &SSB;
QQ.Num = num; Q = &QQ;
HH.Num = num; H = &HH;
PP.Num = num; P = &PP;
YY.Num = num; Y = &YY;
found = 0;
// in curves
tmp = Tree2List(THEM->Curves);
for(i = 0; i < List_Nbr(tmp); i++) {
List_Read(tmp, i, &c);
if((pS = (Simplex **) Tree_PQuery(c->Simplexes, &S))) {
(*pS)->Visible = mode;
found = 1;
break;
}
if((pSB = (SimplexBase **) Tree_PQuery(c->SimplexesBase, &SB))) {
(*pSB)->Visible = mode;
found = 1;
break;
}
}
List_Delete(tmp);
if(found)
break;
// in surfaces
tmp = Tree2List(THEM->Surfaces);
for(i = 0; i < List_Nbr(tmp); i++) {
List_Read(tmp, i, &s);
if((pS = (Simplex **) Tree_PQuery(s->Simplexes, &S))) {
(*pS)->Visible = mode;
found = 1;
break;
}
if((pSB = (SimplexBase **) Tree_PQuery(s->SimplexesBase, &SB))) {
(*pSB)->Visible = mode;
found = 1;
break;
}
if((pQ = (Quadrangle **) Tree_PQuery(s->Quadrangles, &Q))) {
(*pQ)->Visible = mode;
found = 1;
break;
}
}
List_Delete(tmp);
if(found)
break;
// in volumes (this is tricky, since V->Simplexes contains the
// simplexes ordered by quality and not by number; so we use the
// global tree of simplexes here)
if((pS = (Simplex **) Tree_PQuery(THEM->Simplexes, &S))) {
(*pS)->Visible = mode;
break;
}
tmp = Tree2List(THEM->Volumes);
for(i = 0; i < List_Nbr(tmp); i++) {
List_Read(tmp, i, &V);
if((pSB = (SimplexBase **) Tree_PQuery(V->SimplexesBase, &SB))) {
(*pSB)->Visible = mode;
found = 1;
break;
}
if((pH = (Hexahedron **) Tree_PQuery(V->Hexahedra, &H))) {
(*pH)->Visible = mode;
found = 1;
break;
}
if((pP = (Prism **) Tree_PQuery(V->Prisms, &P))) {
(*pP)->Visible = mode;
found = 1;
break;
}
if((pY = (Pyramid **) Tree_PQuery(V->Pyramids, &Y))) {
(*pY)->Visible = mode;
found = 1;
break;
}
}
List_Delete(tmp);
if(!found)
Msg(WARNING, "Unknown element %d (use '*' to hide/show all elements)", num);
break;
case 2: //point
if((v = FindPoint(num, THEM)))
v->Visible = mode;
else
Msg(WARNING, "Unknown point %d (use '*' to hide/show all points)", num);
break;
case 3: //line
if((c = FindCurve(num, THEM)))
c->Visible = mode;
else
Msg(WARNING, "Unknown line %d (use '*' to hide/show all lines)", num);
break;
case 4: //surface
if((s = FindSurface(num, THEM)))
s->Visible = mode;
else
Msg(WARNING, "Unknown surface %d (use '*' to hide/show all surfaces)", num);
break;
case 5: //volume
if((V = FindVolume(num, THEM)))
V->Visible = mode;
else
Msg(WARNING, "Unknown volume %d (use '*' to hide/show all volumes)", num);
break;
}
}
static int vmode;
static void vis_nod(void *a, void *b)
{
(*(Vertex **) a)->Visible = vmode;
}
static void vis_sim(void *a, void *b)
{
(*(SimplexBase **) a)->Visible = vmode;
}
static void vis_qua(void *a, void *b)
{
(*(Quadrangle **) a)->Visible = vmode;
}
static void vis_hex(void *a, void *b)
{
(*(Hexahedron **) a)->Visible = vmode;
}
static void vis_pri(void *a, void *b)
{
(*(Prism **) a)->Visible = vmode;
}
static void vis_pyr(void *a, void *b)
{
(*(Pyramid **) a)->Visible = vmode;
}
static void vis_cur(void *a, void *b)
{
(*(Curve **) a)->Visible = vmode;
}
static void vis_sur(void *a, void *b)
{
(*(Surface **) a)->Visible = vmode;
}
static void vis_vol(void *a, void *b)
{
(*(Volume **) a)->Visible = vmode;
}
void SetVisibilityByNumber(char *str, int type, int mode)
{
int i;
List_T *tmp;
Curve *c;
Surface *s;
Volume *V;
if(!THEM)
return;
vmode = mode;
if(!strcmp(str, "all") || !strcmp(str, "*")) {
switch (type) {
case 0: //node
Tree_Action(THEM->Vertices, vis_nod);
break;
case 1: //element
tmp = Tree2List(THEM->Curves);
for(i = 0; i < List_Nbr(tmp); i++) {
List_Read(tmp, i, &c);
Tree_Action(c->Simplexes, vis_sim);
Tree_Action(c->SimplexesBase, vis_sim);
}
List_Delete(tmp);
tmp = Tree2List(THEM->Surfaces);
for(i = 0; i < List_Nbr(tmp); i++) {
List_Read(tmp, i, &s);
Tree_Action(s->Simplexes, vis_sim);
Tree_Action(s->SimplexesBase, vis_sim);
Tree_Action(s->Quadrangles, vis_qua);
}
List_Delete(tmp);
tmp = Tree2List(THEM->Volumes);
for(i = 0; i < List_Nbr(tmp); i++) {
List_Read(tmp, i, &V);
Tree_Action(V->Simplexes, vis_sim);
Tree_Action(V->SimplexesBase, vis_sim);
Tree_Action(V->Hexahedra, vis_hex);
Tree_Action(V->Prisms, vis_pri);
Tree_Action(V->Pyramids, vis_pyr);
}
List_Delete(tmp);
break;
case 2: //point
Tree_Action(THEM->Points, vis_nod);
break;
case 3: //line
Tree_Action(THEM->Curves, vis_cur);
break;
case 4: //surface
Tree_Action(THEM->Surfaces, vis_sur);
break;
case 5: //volume
Tree_Action(THEM->Volumes, vis_vol);
break;
}
}
else {
SetVisibilityByNumber(atoi(str), type, mode);
}
}