这条线试图做什么?
What is this line trying to do?
我正在尝试编译一个 triangle++ 库(Triangle.h 库的 c++ 包装器),但我卡在了这一行:
else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex)
这显然会引发类型转换错误 (VC++12):
cannot convert from 'piyush::insertvertexresult (__thiscall piyush::* )(piyush::mesh *,piyush::behavior *,piyush::vertex,piyush::otri *,piyush::osub *,int,int)' to 'piyush::flipstacker *'
将函数指针转换为结构指针?这是一些我不知道的黑魔法。
这里是 insertvertex
函数:
enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b,
vertex newvertex, struct otri *searchtri,
struct osub *splitseg,
int segmentflaws, int triflaws)
insertvertexresult
枚举:
/* Labels that signify the result of vertex insertion. The result indicates */
/* that the vertex was inserted with complete success, was inserted but */
/* encroaches upon a subsegment, was not inserted because it lies on a */
/* segment, or was not inserted because another vertex occupies the same */
/* location. */
enum insertvertexresult {SUCCESSFULVERTEX, ENCROACHINGVERTEX, VIOLATINGVERTEX,
DUPLICATEVERTEX};
flipstacker
结构:
/* A stack of triangles flipped during the most recent vertex insertion. */
/* The stack is used to undo the vertex insertion if the vertex encroaches */
/* upon a subsegment. */
struct flipstacker {
triangle flippedtri; /* A recently flipped triangle. */
struct flipstacker *prevflip; /* Previous flip in the stack. */
};
为方便起见的完整上下文(找到上面转换的undovertex函数):
/*****************************************************************************/
/* */
/* undovertex() Undo the most recent vertex insertion. */
/* */
/* Walks through the list of transformations (flips and a vertex insertion) */
/* in the reverse of the order in which they were done, and undoes them. */
/* The inserted vertex is removed from the triangulation and deallocated. */
/* Two triangles (possibly just one) are also deallocated. */
/* */
/*****************************************************************************/
void undovertex(struct mesh *m, struct behavior *b)
{
struct otri fliptri;
struct otri botleft, botright, topright;
struct otri botlcasing, botrcasing, toprcasing;
struct otri gluetri;
struct osub botlsubseg, botrsubseg, toprsubseg;
vertex botvertex, rightvertex;
triangle ptr; /* Temporary variable used by sym(). */
subseg sptr; /* Temporary variable used by tspivot(). */
/* Walk through the list of transformations (flips and a vertex insertion) */
/* in the reverse of the order in which they were done, and undo them. */
while (m->lastflip != (struct flipstacker *) NULL) {
/* Find a triangle involved in the last unreversed transformation. */
decode(m->lastflip->flippedtri, fliptri);
/* We are reversing one of three transformations: a trisection of one */
/* triangle into three (by inserting a vertex in the triangle), a */
/* bisection of two triangles into four (by inserting a vertex in an */
/* edge), or an edge flip. */
if (m->lastflip->prevflip == (struct flipstacker *) NULL) {
/* Restore a triangle that was split into three triangles, */
/* so it is again one triangle. */
dprev(fliptri, botleft);
lnextself(botleft);
onext(fliptri, botright);
lprevself(botright);
sym(botleft, botlcasing);
sym(botright, botrcasing);
dest(botleft, botvertex);
setapex(fliptri, botvertex);
lnextself(fliptri);
bond(fliptri, botlcasing);
tspivot(botleft, botlsubseg);
tsbond(fliptri, botlsubseg);
lnextself(fliptri);
bond(fliptri, botrcasing);
tspivot(botright, botrsubseg);
tsbond(fliptri, botrsubseg);
/* Delete the two spliced-out triangles. */
triangledealloc(m, botleft.tri);
triangledealloc(m, botright.tri);
} else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex) {
/* Restore two triangles that were split into four triangles, */
/* so they are again two triangles. */
lprev(fliptri, gluetri);
sym(gluetri, botright);
lnextself(botright);
sym(botright, botrcasing);
dest(botright, rightvertex);
setorg(fliptri, rightvertex);
bond(gluetri, botrcasing);
tspivot(botright, botrsubseg);
tsbond(gluetri, botrsubseg);
/* Delete the spliced-out triangle. */
triangledealloc(m, botright.tri);
sym(fliptri, gluetri);
if (gluetri.tri != m->dummytri) {
lnextself(gluetri);
dnext(gluetri, topright);
sym(topright, toprcasing);
setorg(gluetri, rightvertex);
bond(gluetri, toprcasing);
tspivot(topright, toprsubseg);
tsbond(gluetri, toprsubseg);
/* Delete the spliced-out triangle. */
triangledealloc(m, topright.tri);
}
/* This is the end of the list, sneakily encoded. */
m->lastflip->prevflip = (struct flipstacker *) NULL;
} else {
/* Undo an edge flip. */
unflip(m, b, &fliptri);
}
/* Go on and process the next transformation. */
m->lastflip = m->lastflip->prevflip;
}
}
我的问题是,这样的演员试图完成什么,为什么这甚至可能?
现在演员表确实没有任何意义。
但是稍微浏览一下代码后,我发现了这个:
if (m->checkquality) {
poolrestart(&m->flipstackers);
m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
m->lastflip->flippedtri = encode(horiz);
printf("Fatal Error: Contact piyush\n");
exit(1);
/*
m->lastflip->prevflip = (struct flipstacker *) &insertvertex;
*/
}
请注意,还有同样奇怪的演员表,但这次是作业。
所以有两种可能:
要么在某个时间点 insertvertex
不是一个函数,而是一个实际上可以转换为 (struct flipstacker *)
、
的对象
或者作者使用 insertvertex
的地址作为魔法值,知道没有有效的 flipstacker
对象可以与 insertvertex
位于同一地址函数,而作者的编译器不知何故从不抱怨。
无论哪种方式,这都是一种糟糕的做法,并且既然魔法赋值已被注释掉,这种情况看起来基本上是死代码,我建议填写错误报告并同时将其删除。
我正在尝试编译一个 triangle++ 库(Triangle.h 库的 c++ 包装器),但我卡在了这一行:
else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex)
这显然会引发类型转换错误 (VC++12):
cannot convert from 'piyush::insertvertexresult (__thiscall piyush::* )(piyush::mesh *,piyush::behavior *,piyush::vertex,piyush::otri *,piyush::osub *,int,int)' to 'piyush::flipstacker *'
将函数指针转换为结构指针?这是一些我不知道的黑魔法。
这里是 insertvertex
函数:
enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b,
vertex newvertex, struct otri *searchtri,
struct osub *splitseg,
int segmentflaws, int triflaws)
insertvertexresult
枚举:
/* Labels that signify the result of vertex insertion. The result indicates */
/* that the vertex was inserted with complete success, was inserted but */
/* encroaches upon a subsegment, was not inserted because it lies on a */
/* segment, or was not inserted because another vertex occupies the same */
/* location. */
enum insertvertexresult {SUCCESSFULVERTEX, ENCROACHINGVERTEX, VIOLATINGVERTEX,
DUPLICATEVERTEX};
flipstacker
结构:
/* A stack of triangles flipped during the most recent vertex insertion. */
/* The stack is used to undo the vertex insertion if the vertex encroaches */
/* upon a subsegment. */
struct flipstacker {
triangle flippedtri; /* A recently flipped triangle. */
struct flipstacker *prevflip; /* Previous flip in the stack. */
};
为方便起见的完整上下文(找到上面转换的undovertex函数):
/*****************************************************************************/
/* */
/* undovertex() Undo the most recent vertex insertion. */
/* */
/* Walks through the list of transformations (flips and a vertex insertion) */
/* in the reverse of the order in which they were done, and undoes them. */
/* The inserted vertex is removed from the triangulation and deallocated. */
/* Two triangles (possibly just one) are also deallocated. */
/* */
/*****************************************************************************/
void undovertex(struct mesh *m, struct behavior *b)
{
struct otri fliptri;
struct otri botleft, botright, topright;
struct otri botlcasing, botrcasing, toprcasing;
struct otri gluetri;
struct osub botlsubseg, botrsubseg, toprsubseg;
vertex botvertex, rightvertex;
triangle ptr; /* Temporary variable used by sym(). */
subseg sptr; /* Temporary variable used by tspivot(). */
/* Walk through the list of transformations (flips and a vertex insertion) */
/* in the reverse of the order in which they were done, and undo them. */
while (m->lastflip != (struct flipstacker *) NULL) {
/* Find a triangle involved in the last unreversed transformation. */
decode(m->lastflip->flippedtri, fliptri);
/* We are reversing one of three transformations: a trisection of one */
/* triangle into three (by inserting a vertex in the triangle), a */
/* bisection of two triangles into four (by inserting a vertex in an */
/* edge), or an edge flip. */
if (m->lastflip->prevflip == (struct flipstacker *) NULL) {
/* Restore a triangle that was split into three triangles, */
/* so it is again one triangle. */
dprev(fliptri, botleft);
lnextself(botleft);
onext(fliptri, botright);
lprevself(botright);
sym(botleft, botlcasing);
sym(botright, botrcasing);
dest(botleft, botvertex);
setapex(fliptri, botvertex);
lnextself(fliptri);
bond(fliptri, botlcasing);
tspivot(botleft, botlsubseg);
tsbond(fliptri, botlsubseg);
lnextself(fliptri);
bond(fliptri, botrcasing);
tspivot(botright, botrsubseg);
tsbond(fliptri, botrsubseg);
/* Delete the two spliced-out triangles. */
triangledealloc(m, botleft.tri);
triangledealloc(m, botright.tri);
} else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex) {
/* Restore two triangles that were split into four triangles, */
/* so they are again two triangles. */
lprev(fliptri, gluetri);
sym(gluetri, botright);
lnextself(botright);
sym(botright, botrcasing);
dest(botright, rightvertex);
setorg(fliptri, rightvertex);
bond(gluetri, botrcasing);
tspivot(botright, botrsubseg);
tsbond(gluetri, botrsubseg);
/* Delete the spliced-out triangle. */
triangledealloc(m, botright.tri);
sym(fliptri, gluetri);
if (gluetri.tri != m->dummytri) {
lnextself(gluetri);
dnext(gluetri, topright);
sym(topright, toprcasing);
setorg(gluetri, rightvertex);
bond(gluetri, toprcasing);
tspivot(topright, toprsubseg);
tsbond(gluetri, toprsubseg);
/* Delete the spliced-out triangle. */
triangledealloc(m, topright.tri);
}
/* This is the end of the list, sneakily encoded. */
m->lastflip->prevflip = (struct flipstacker *) NULL;
} else {
/* Undo an edge flip. */
unflip(m, b, &fliptri);
}
/* Go on and process the next transformation. */
m->lastflip = m->lastflip->prevflip;
}
}
我的问题是,这样的演员试图完成什么,为什么这甚至可能?
现在演员表确实没有任何意义。
但是稍微浏览一下代码后,我发现了这个:
if (m->checkquality) {
poolrestart(&m->flipstackers);
m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
m->lastflip->flippedtri = encode(horiz);
printf("Fatal Error: Contact piyush\n");
exit(1);
/*
m->lastflip->prevflip = (struct flipstacker *) &insertvertex;
*/
}
请注意,还有同样奇怪的演员表,但这次是作业。
所以有两种可能:
要么在某个时间点
insertvertex
不是一个函数,而是一个实际上可以转换为(struct flipstacker *)
、 的对象
或者作者使用
insertvertex
的地址作为魔法值,知道没有有效的flipstacker
对象可以与insertvertex
位于同一地址函数,而作者的编译器不知何故从不抱怨。
无论哪种方式,这都是一种糟糕的做法,并且既然魔法赋值已被注释掉,这种情况看起来基本上是死代码,我建议填写错误报告并同时将其删除。