File: polytess.c

package info (click to toggle)
graphviz 14.0.5-2
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 139,388 kB
  • sloc: ansic: 141,938; cpp: 11,957; python: 7,766; makefile: 4,043; yacc: 3,030; xml: 2,972; tcl: 2,495; sh: 1,388; objc: 1,159; java: 560; lex: 423; perl: 243; awk: 156; pascal: 139; php: 58; ruby: 49; cs: 31; sed: 1
file content (122 lines) | stat: -rw-r--r-- 3,679 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*************************************************************************
 * Copyright (c) 2011 AT&T Intellectual Property 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors: Details at https://graphviz.org
 *************************************************************************/

#include "polytess.h"
#include <stddef.h>
#include <util/alloc.h>
#include <xdot/xdot.h>
tessPoly TP;

#ifndef _WIN32
#define CALLBACK 
#endif
static void CALLBACK combineCallback(double coords[3],
                                     double *vertex_data[4],
                                     float weight[4],
                                     double **dataOut) {
    (void)vertex_data;
    (void)weight;

    int i;
    double *vertex = gv_calloc(6, sizeof(double));
    vertex[0] = coords[0];
    vertex[1] = coords[1];
    vertex[2] = coords[2];
    for (i = 3; i < 6; i++)
    {
	vertex[i] = 0;

    }
    *dataOut = vertex;
}

static void CALLBACK vertexCallback(void *vertex) {
  glVertex3dv(vertex);
}

// OpenGL’s `gluTessCallback` function has a prototype indicating it takes a
// `void(*)(void)`. But its documentation describes passing in various function
// pointers with differing calling conventions. To use this API while also
// pacifying all the various build environments, we need this rather silly
// wrapper.
#ifdef _MSC_VER
// MSVC is of the (correct) opinion that casting between function pointers of
// incompatible calling conventions is unacceptable behavior…
#define MAKE_GLU_CALLBACK(f) f
#else
// …nevertheless other compilers insist we cast or they believe we have made a
// typo
#define MAKE_GLU_CALLBACK(f) ((void (*)(void))(f))
#endif

static GLUtesselator* Init(void)
{
    // Create a new tessellation object 
    GLUtesselator* tobj = gluNewTess(); 
    // Set callback functions
    gluTessCallback(tobj, GLU_TESS_VERTEX, MAKE_GLU_CALLBACK(vertexCallback));
    gluTessCallback(tobj, GLU_TESS_BEGIN, MAKE_GLU_CALLBACK(glBegin));
    gluTessCallback(tobj, GLU_TESS_END, MAKE_GLU_CALLBACK(glEnd));
    gluTessCallback(tobj, GLU_TESS_COMBINE, MAKE_GLU_CALLBACK(combineCallback));
    return tobj;
}

static void Set_Winding_Rule(GLUtesselator *tobj, GLenum winding_rule)
{
// Set the winding rule
    gluTessProperty(tobj, GLU_TESS_WINDING_RULE, winding_rule); 
}

static void Render_Contour2(GLUtesselator *tobj, sdot_op* p)
{
    double *d = gv_calloc(p->op.u.polygon.cnt * 3, sizeof(double));
    for (size_t x = 0; x < p->op.u.polygon.cnt; x++)
    {
        d[x * 3] = p->op.u.polygon.pts[x].x;
        d[x * 3 + 1] = p->op.u.polygon.pts[x].y;
        d[x * 3 + 2] = p->op.u.polygon.pts[x].z + view->Topview->global_z;
    }
    for (size_t x = 0; x < p->op.u.polygon.cnt; x++) //loop through the vertices
    {
        gluTessVertex(tobj, &d[x * 3], &d[x * 3]); //store the vertex
    }
}

static void Begin_Polygon(GLUtesselator *tobj)
{
    gluTessBeginPolygon(tobj, NULL);
}
static void End_Polygon(GLUtesselator *tobj)
{
    gluTessEndPolygon(tobj);
}
static void Begin_Contour(GLUtesselator *tobj)
{
    gluTessBeginContour(tobj);
}
static void End_Contour(GLUtesselator *tobj)
{
    gluTessEndContour(tobj);
}

void drawTessPolygon(sdot_op* p)
{
    if (!TP.tobj)
    {
	TP.tobj=Init();
	TP.windingRule=GLU_TESS_WINDING_ODD;
    }
    Set_Winding_Rule(TP.tobj,TP.windingRule);
    Begin_Polygon(TP.tobj); 
    Begin_Contour(TP.tobj);
    Render_Contour2(TP.tobj,p); 
    End_Contour(TP.tobj);
    End_Polygon(TP.tobj);
}