working wasm connection
parent
f3f04f9cfb
commit
ec59e95b87
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -61,7 +61,8 @@
|
||||||
<div id="view2"></div>
|
<div id="view2"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="solver.js">
|
||||||
|
</script>
|
||||||
<script src="bundle.js" type="module"></script>
|
<script src="bundle.js" type="module"></script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
import { Matrix4 } from 'three';
|
import { Matrix4 } from 'three';
|
||||||
|
|
||||||
import * as THREE from '../node_modules/three/src/Three'
|
import * as THREE from '../node_modules/three/src/Three'
|
||||||
|
|
||||||
export class Sketcher extends THREE.Group {
|
export class Sketcher extends THREE.Group {
|
||||||
|
@ -53,11 +54,6 @@ export class Sketcher extends THREE.Group {
|
||||||
|
|
||||||
|
|
||||||
this.mode = ""
|
this.mode = ""
|
||||||
this.keyTable = {
|
|
||||||
'l': this.addLine,
|
|
||||||
'Escape': this.clear
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -84,6 +80,9 @@ export class Sketcher extends THREE.Group {
|
||||||
this.addLine()
|
this.addLine()
|
||||||
this.mode = "line"
|
this.mode = "line"
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
this.writeBuff()
|
||||||
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
this.plane.applyMatrix4(new Matrix4().makeRotationY(0.1))
|
this.plane.applyMatrix4(new Matrix4().makeRotationY(0.1))
|
||||||
this.orientSketcher()
|
this.orientSketcher()
|
||||||
|
@ -259,7 +258,29 @@ export class Sketcher extends THREE.Group {
|
||||||
this.pointStart(e)
|
this.pointStart(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeBuff() {
|
||||||
|
// const linesBuf = new Float32Array(this.linesArr.length * 4)
|
||||||
|
// const xyOnly = [0,1,3,4];
|
||||||
|
// let p = 0
|
||||||
|
// for (let i = 0; i < this.linesArr.length; i++) {
|
||||||
|
// for (let j of xyOnly) {
|
||||||
|
// linesBuf[p++] = this.linesArr[i].geometry.attributes.position.array[j]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
let ptsBuf = new Float32Array(this.ptsArr.length * 2)
|
||||||
|
for (let i = 0, p = 0; i < this.ptsArr.length; i++) {
|
||||||
|
for (let j = 0; j < 2; j++) {
|
||||||
|
ptsBuf[p++] = this.ptsArr[i].geometry.attributes.position.array[j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(ptsBuf)
|
||||||
|
|
||||||
|
buffer = Module._malloc(ptsBuf.length * ptsBuf.BYTES_PER_ELEMENT)
|
||||||
|
Module.HEAPF32.set(ptsBuf, buffer >> 2)
|
||||||
|
|
||||||
|
Module["_solver"](buffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
emcc ./wasm/solver.c ./wasm/libslvs.a -L./wasm/ -lslvs -o ./dist/solver.js -s TOTAL_MEMORY=134217728 -s EXPORTED_FUNCTIONS='[_main, _solver]'
|
|
@ -0,0 +1,404 @@
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* Data structures and prototypes for slvs.lib, a geometric constraint solver.
|
||||||
|
*
|
||||||
|
* See the comments in this file, the accompanying sample code that uses
|
||||||
|
* this library, and the accompanying documentation (DOC.txt).
|
||||||
|
*
|
||||||
|
* Copyright 2009-2013 Jonathan Westhues.
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __SLVS_H
|
||||||
|
#define __SLVS_H
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# ifdef EXPORT_DLL
|
||||||
|
# define DLL __declspec( dllexport )
|
||||||
|
# else
|
||||||
|
# define DLL __declspec( dllimport )
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define DLL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint32_t Slvs_hParam;
|
||||||
|
typedef uint32_t Slvs_hEntity;
|
||||||
|
typedef uint32_t Slvs_hConstraint;
|
||||||
|
typedef uint32_t Slvs_hGroup;
|
||||||
|
|
||||||
|
/* To obtain the 3d (not projected into a workplane) of a constraint or
|
||||||
|
* an entity, specify this instead of the workplane. */
|
||||||
|
#define SLVS_FREE_IN_3D 0
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Slvs_hParam h;
|
||||||
|
Slvs_hGroup group;
|
||||||
|
double val;
|
||||||
|
} Slvs_Param;
|
||||||
|
|
||||||
|
|
||||||
|
#define SLVS_E_POINT_IN_3D 50000
|
||||||
|
#define SLVS_E_POINT_IN_2D 50001
|
||||||
|
|
||||||
|
#define SLVS_E_NORMAL_IN_3D 60000
|
||||||
|
#define SLVS_E_NORMAL_IN_2D 60001
|
||||||
|
|
||||||
|
#define SLVS_E_DISTANCE 70000
|
||||||
|
|
||||||
|
/* The special point, normal, and distance types used for parametric step
|
||||||
|
* and repeat, extrude, and assembly are currently not exposed. Please
|
||||||
|
* contact us if you are interested in using these. */
|
||||||
|
|
||||||
|
#define SLVS_E_WORKPLANE 80000
|
||||||
|
#define SLVS_E_LINE_SEGMENT 80001
|
||||||
|
#define SLVS_E_CUBIC 80002
|
||||||
|
#define SLVS_E_CIRCLE 80003
|
||||||
|
#define SLVS_E_ARC_OF_CIRCLE 80004
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Slvs_hEntity h;
|
||||||
|
Slvs_hGroup group;
|
||||||
|
|
||||||
|
int type;
|
||||||
|
|
||||||
|
Slvs_hEntity wrkpl;
|
||||||
|
Slvs_hEntity point[4];
|
||||||
|
Slvs_hEntity normal;
|
||||||
|
Slvs_hEntity distance;
|
||||||
|
|
||||||
|
Slvs_hParam param[4];
|
||||||
|
} Slvs_Entity;
|
||||||
|
|
||||||
|
#define SLVS_C_POINTS_COINCIDENT 100000
|
||||||
|
#define SLVS_C_PT_PT_DISTANCE 100001
|
||||||
|
#define SLVS_C_PT_PLANE_DISTANCE 100002
|
||||||
|
#define SLVS_C_PT_LINE_DISTANCE 100003
|
||||||
|
#define SLVS_C_PT_FACE_DISTANCE 100004
|
||||||
|
#define SLVS_C_PT_IN_PLANE 100005
|
||||||
|
#define SLVS_C_PT_ON_LINE 100006
|
||||||
|
#define SLVS_C_PT_ON_FACE 100007
|
||||||
|
#define SLVS_C_EQUAL_LENGTH_LINES 100008
|
||||||
|
#define SLVS_C_LENGTH_RATIO 100009
|
||||||
|
#define SLVS_C_EQ_LEN_PT_LINE_D 100010
|
||||||
|
#define SLVS_C_EQ_PT_LN_DISTANCES 100011
|
||||||
|
#define SLVS_C_EQUAL_ANGLE 100012
|
||||||
|
#define SLVS_C_EQUAL_LINE_ARC_LEN 100013
|
||||||
|
#define SLVS_C_SYMMETRIC 100014
|
||||||
|
#define SLVS_C_SYMMETRIC_HORIZ 100015
|
||||||
|
#define SLVS_C_SYMMETRIC_VERT 100016
|
||||||
|
#define SLVS_C_SYMMETRIC_LINE 100017
|
||||||
|
#define SLVS_C_AT_MIDPOINT 100018
|
||||||
|
#define SLVS_C_HORIZONTAL 100019
|
||||||
|
#define SLVS_C_VERTICAL 100020
|
||||||
|
#define SLVS_C_DIAMETER 100021
|
||||||
|
#define SLVS_C_PT_ON_CIRCLE 100022
|
||||||
|
#define SLVS_C_SAME_ORIENTATION 100023
|
||||||
|
#define SLVS_C_ANGLE 100024
|
||||||
|
#define SLVS_C_PARALLEL 100025
|
||||||
|
#define SLVS_C_PERPENDICULAR 100026
|
||||||
|
#define SLVS_C_ARC_LINE_TANGENT 100027
|
||||||
|
#define SLVS_C_CUBIC_LINE_TANGENT 100028
|
||||||
|
#define SLVS_C_EQUAL_RADIUS 100029
|
||||||
|
#define SLVS_C_PROJ_PT_DISTANCE 100030
|
||||||
|
#define SLVS_C_WHERE_DRAGGED 100031
|
||||||
|
#define SLVS_C_CURVE_CURVE_TANGENT 100032
|
||||||
|
#define SLVS_C_LENGTH_DIFFERENCE 100033
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Slvs_hConstraint h;
|
||||||
|
Slvs_hGroup group;
|
||||||
|
|
||||||
|
int type;
|
||||||
|
|
||||||
|
Slvs_hEntity wrkpl;
|
||||||
|
|
||||||
|
double valA;
|
||||||
|
Slvs_hEntity ptA;
|
||||||
|
Slvs_hEntity ptB;
|
||||||
|
Slvs_hEntity entityA;
|
||||||
|
Slvs_hEntity entityB;
|
||||||
|
Slvs_hEntity entityC;
|
||||||
|
Slvs_hEntity entityD;
|
||||||
|
|
||||||
|
int other;
|
||||||
|
int other2;
|
||||||
|
} Slvs_Constraint;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/*** INPUT VARIABLES
|
||||||
|
*
|
||||||
|
* Here, we specify the parameters and their initial values, the entities,
|
||||||
|
* and the constraints. For example, param[] points to the array of
|
||||||
|
* parameters, which has length params, so that the last valid element
|
||||||
|
* is param[params-1].
|
||||||
|
*
|
||||||
|
* param[] is actually an in/out variable; if the solver is successful,
|
||||||
|
* then the new values (that satisfy the constraints) are written to it. */
|
||||||
|
Slvs_Param *param;
|
||||||
|
int params;
|
||||||
|
Slvs_Entity *entity;
|
||||||
|
int entities;
|
||||||
|
Slvs_Constraint *constraint;
|
||||||
|
int constraints;
|
||||||
|
|
||||||
|
/* If a parameter corresponds to a point (distance, normal, etc.) being
|
||||||
|
* dragged, then specify it here. This will cause the solver to favor
|
||||||
|
* that parameter, and attempt to change it as little as possible even
|
||||||
|
* if that requires it to change other parameters more.
|
||||||
|
*
|
||||||
|
* Unused members of this array should be set to zero. */
|
||||||
|
Slvs_hParam dragged[4];
|
||||||
|
|
||||||
|
/* If the solver fails, then it can determine which constraints are
|
||||||
|
* causing the problem. But this is a relatively slow process (for
|
||||||
|
* a system with n constraints, about n times as long as just solving).
|
||||||
|
* If calculateFaileds is true, then the solver will do so, otherwise
|
||||||
|
* not. */
|
||||||
|
int calculateFaileds;
|
||||||
|
|
||||||
|
/*** OUTPUT VARIABLES
|
||||||
|
*
|
||||||
|
* If the solver fails, then it can report which constraints are causing
|
||||||
|
* the problem. The caller should allocate the array failed[], and pass
|
||||||
|
* its size in faileds.
|
||||||
|
*
|
||||||
|
* The solver will set faileds equal to the number of problematic
|
||||||
|
* constraints, and write their Slvs_hConstraints into failed[]. To
|
||||||
|
* ensure that there is sufficient space for any possible set of
|
||||||
|
* failing constraints, faileds should be greater than or equal to
|
||||||
|
* constraints. */
|
||||||
|
Slvs_hConstraint *failed;
|
||||||
|
int faileds;
|
||||||
|
|
||||||
|
/* The solver indicates the number of unconstrained degrees of freedom. */
|
||||||
|
int dof;
|
||||||
|
|
||||||
|
/* The solver indicates whether the solution succeeded. */
|
||||||
|
#define SLVS_RESULT_OKAY 0
|
||||||
|
#define SLVS_RESULT_INCONSISTENT 1
|
||||||
|
#define SLVS_RESULT_DIDNT_CONVERGE 2
|
||||||
|
#define SLVS_RESULT_TOO_MANY_UNKNOWNS 3
|
||||||
|
int result;
|
||||||
|
} Slvs_System;
|
||||||
|
|
||||||
|
DLL void Slvs_Solve(Slvs_System *sys, Slvs_hGroup hg);
|
||||||
|
|
||||||
|
|
||||||
|
/* Our base coordinate system has basis vectors
|
||||||
|
* (1, 0, 0) (0, 1, 0) (0, 0, 1)
|
||||||
|
* A unit quaternion defines a rotation to a new coordinate system with
|
||||||
|
* basis vectors
|
||||||
|
* U V N
|
||||||
|
* which these functions compute from the quaternion. */
|
||||||
|
DLL void Slvs_QuaternionU(double qw, double qx, double qy, double qz,
|
||||||
|
double *x, double *y, double *z);
|
||||||
|
DLL void Slvs_QuaternionV(double qw, double qx, double qy, double qz,
|
||||||
|
double *x, double *y, double *z);
|
||||||
|
DLL void Slvs_QuaternionN(double qw, double qx, double qy, double qz,
|
||||||
|
double *x, double *y, double *z);
|
||||||
|
|
||||||
|
/* Similarly, compute a unit quaternion in terms of two basis vectors. */
|
||||||
|
DLL void Slvs_MakeQuaternion(double ux, double uy, double uz,
|
||||||
|
double vx, double vy, double vz,
|
||||||
|
double *qw, double *qx, double *qy, double *qz);
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------
|
||||||
|
* These are just convenience functions, to save you the trouble of filling
|
||||||
|
* out the structures by hand. The code is included in the header file to
|
||||||
|
* let the compiler inline them if possible. */
|
||||||
|
|
||||||
|
static inline Slvs_Param Slvs_MakeParam(Slvs_hParam h, Slvs_hGroup group, double val)
|
||||||
|
{
|
||||||
|
Slvs_Param r;
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.val = val;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakePoint2d(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hEntity wrkpl,
|
||||||
|
Slvs_hParam u, Slvs_hParam v)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_POINT_IN_2D;
|
||||||
|
r.wrkpl = wrkpl;
|
||||||
|
r.param[0] = u;
|
||||||
|
r.param[1] = v;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakePoint3d(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hParam x, Slvs_hParam y, Slvs_hParam z)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_POINT_IN_3D;
|
||||||
|
r.wrkpl = SLVS_FREE_IN_3D;
|
||||||
|
r.param[0] = x;
|
||||||
|
r.param[1] = y;
|
||||||
|
r.param[2] = z;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakeNormal3d(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hParam qw, Slvs_hParam qx,
|
||||||
|
Slvs_hParam qy, Slvs_hParam qz)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_NORMAL_IN_3D;
|
||||||
|
r.wrkpl = SLVS_FREE_IN_3D;
|
||||||
|
r.param[0] = qw;
|
||||||
|
r.param[1] = qx;
|
||||||
|
r.param[2] = qy;
|
||||||
|
r.param[3] = qz;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakeNormal2d(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hEntity wrkpl)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_NORMAL_IN_2D;
|
||||||
|
r.wrkpl = wrkpl;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakeDistance(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hEntity wrkpl, Slvs_hParam d)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_DISTANCE;
|
||||||
|
r.wrkpl = wrkpl;
|
||||||
|
r.param[0] = d;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakeLineSegment(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hEntity wrkpl,
|
||||||
|
Slvs_hEntity ptA, Slvs_hEntity ptB)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_LINE_SEGMENT;
|
||||||
|
r.wrkpl = wrkpl;
|
||||||
|
r.point[0] = ptA;
|
||||||
|
r.point[1] = ptB;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakeCubic(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hEntity wrkpl,
|
||||||
|
Slvs_hEntity pt0, Slvs_hEntity pt1,
|
||||||
|
Slvs_hEntity pt2, Slvs_hEntity pt3)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_CUBIC;
|
||||||
|
r.wrkpl = wrkpl;
|
||||||
|
r.point[0] = pt0;
|
||||||
|
r.point[1] = pt1;
|
||||||
|
r.point[2] = pt2;
|
||||||
|
r.point[3] = pt3;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakeArcOfCircle(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hEntity wrkpl,
|
||||||
|
Slvs_hEntity normal,
|
||||||
|
Slvs_hEntity center,
|
||||||
|
Slvs_hEntity start, Slvs_hEntity end)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_ARC_OF_CIRCLE;
|
||||||
|
r.wrkpl = wrkpl;
|
||||||
|
r.normal = normal;
|
||||||
|
r.point[0] = center;
|
||||||
|
r.point[1] = start;
|
||||||
|
r.point[2] = end;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakeCircle(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hEntity wrkpl,
|
||||||
|
Slvs_hEntity center,
|
||||||
|
Slvs_hEntity normal, Slvs_hEntity radius)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_CIRCLE;
|
||||||
|
r.wrkpl = wrkpl;
|
||||||
|
r.point[0] = center;
|
||||||
|
r.normal = normal;
|
||||||
|
r.distance = radius;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
static inline Slvs_Entity Slvs_MakeWorkplane(Slvs_hEntity h, Slvs_hGroup group,
|
||||||
|
Slvs_hEntity origin, Slvs_hEntity normal)
|
||||||
|
{
|
||||||
|
Slvs_Entity r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = SLVS_E_WORKPLANE;
|
||||||
|
r.wrkpl = SLVS_FREE_IN_3D;
|
||||||
|
r.point[0] = origin;
|
||||||
|
r.normal = normal;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Slvs_Constraint Slvs_MakeConstraint(Slvs_hConstraint h,
|
||||||
|
Slvs_hGroup group,
|
||||||
|
int type,
|
||||||
|
Slvs_hEntity wrkpl,
|
||||||
|
double valA,
|
||||||
|
Slvs_hEntity ptA,
|
||||||
|
Slvs_hEntity ptB,
|
||||||
|
Slvs_hEntity entityA,
|
||||||
|
Slvs_hEntity entityB)
|
||||||
|
{
|
||||||
|
Slvs_Constraint r;
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.h = h;
|
||||||
|
r.group = group;
|
||||||
|
r.type = type;
|
||||||
|
r.wrkpl = wrkpl;
|
||||||
|
r.valA = valA;
|
||||||
|
r.ptA = ptA;
|
||||||
|
r.ptB = ptB;
|
||||||
|
r.entityA = entityA;
|
||||||
|
r.entityB = entityB;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,281 @@
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* Some sample code for slvs.dll. We draw some geometric entities, provide
|
||||||
|
* initial guesses for their positions, and then constrain them. The solver
|
||||||
|
* calculates their new positions, in order to satisfy the constraints.
|
||||||
|
*
|
||||||
|
* Copyright 2008-2013 Jonathan Westhues.
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "slvs.h"
|
||||||
|
|
||||||
|
static Slvs_System sys;
|
||||||
|
|
||||||
|
static void *CheckMalloc(size_t n)
|
||||||
|
{
|
||||||
|
void *r = malloc(n);
|
||||||
|
if(!r) {
|
||||||
|
printf("out of memory!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* An example of a constraint in 3d. We create a single group, with some
|
||||||
|
* entities and constraints.
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
void Example3d()
|
||||||
|
{
|
||||||
|
/* This will contain a single group, which will arbitrarily number 1. */
|
||||||
|
Slvs_hGroup g = 1;
|
||||||
|
|
||||||
|
/* A point, initially at (x y z) = (10 10 10) */
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(1, g, 10.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(2, g, 10.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(3, g, 10.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3);
|
||||||
|
/* and a second point at (20 20 20) */
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(4, g, 20.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(5, g, 20.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(6, g, 20.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint3d(102, g, 4, 5, 6);
|
||||||
|
/* and a line segment connecting them. */
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakeLineSegment(200, g,
|
||||||
|
SLVS_FREE_IN_3D, 101, 102);
|
||||||
|
|
||||||
|
/* The distance between the points should be 30.0 units. */
|
||||||
|
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||||
|
1, g,
|
||||||
|
SLVS_C_PT_PT_DISTANCE,
|
||||||
|
SLVS_FREE_IN_3D,
|
||||||
|
30.0,
|
||||||
|
101, 102, 0, 0);
|
||||||
|
|
||||||
|
/* Let's tell the solver to keep the second point as close to constant
|
||||||
|
* as possible, instead moving the first point. */
|
||||||
|
sys.dragged[0] = 4;
|
||||||
|
sys.dragged[1] = 5;
|
||||||
|
sys.dragged[2] = 6;
|
||||||
|
|
||||||
|
/* Now that we have written our system, we solve. */
|
||||||
|
Slvs_Solve(&sys, g);
|
||||||
|
|
||||||
|
if(sys.result == SLVS_RESULT_OKAY) {
|
||||||
|
printf("okay; now at (%.3f %.3f %.3f)\n"
|
||||||
|
" (%.3f %.3f %.3f)\n",
|
||||||
|
sys.param[0].val, sys.param[1].val, sys.param[2].val,
|
||||||
|
sys.param[3].val, sys.param[4].val, sys.param[5].val);
|
||||||
|
printf("%d DOF\n", sys.dof);
|
||||||
|
} else {
|
||||||
|
printf("solve failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* An example of a constraint in 2d. In our first group, we create a workplane
|
||||||
|
* along the reference frame's xy plane. In a second group, we create some
|
||||||
|
* entities in that group and dimension them.
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
void Example2d(float xx)
|
||||||
|
{
|
||||||
|
Slvs_hGroup g;
|
||||||
|
double qw, qx, qy, qz;
|
||||||
|
|
||||||
|
g = 1;
|
||||||
|
/* First, we create our workplane. Its origin corresponds to the origin
|
||||||
|
* of our base frame (x y z) = (0 0 0) */
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(1, g, 0.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(2, g, 0.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(3, g, 0.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3);
|
||||||
|
/* and it is parallel to the xy plane, so it has basis vectors (1 0 0)
|
||||||
|
* and (0 1 0). */
|
||||||
|
Slvs_MakeQuaternion(1, 0, 0,
|
||||||
|
0, 1, 0, &qw, &qx, &qy, &qz);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(4, g, qw);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(5, g, qx);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(6, g, qy);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(7, g, qz);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakeNormal3d(102, g, 4, 5, 6, 7);
|
||||||
|
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakeWorkplane(200, g, 101, 102);
|
||||||
|
|
||||||
|
/* Now create a second group. We'll solve group 2, while leaving group 1
|
||||||
|
* constant; so the workplane that we've created will be locked down,
|
||||||
|
* and the solver can't move it. */
|
||||||
|
g = 2;
|
||||||
|
/* These points are represented by their coordinates (u v) within the
|
||||||
|
* workplane, so they need only two parameters each. */
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(11, g, 10.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(12, g, 20.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint2d(301, g, 200, 11, 12);
|
||||||
|
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(13, g, 20.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(14, g, 10.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint2d(302, g, 200, 13, 14);
|
||||||
|
|
||||||
|
/* And we create a line segment with those endpoints. */
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakeLineSegment(400, g,
|
||||||
|
200, 301, 302);
|
||||||
|
|
||||||
|
/* Now three more points. */
|
||||||
|
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(15, g, 110.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(16, g, 120.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint2d(303, g, 200, 15, 16);
|
||||||
|
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(17, g, 120.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(18, g, 110.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint2d(304, g, 200, 17, 18);
|
||||||
|
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(19, g, 115.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(20, g, xx);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint2d(305, g, 200, 19, 20);
|
||||||
|
|
||||||
|
/* And arc, centered at point 303, starting at point 304, ending at
|
||||||
|
* point 305. */
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakeArcOfCircle(401, g, 200, 102,
|
||||||
|
303, 304, 305);
|
||||||
|
|
||||||
|
/* Now one more point, and a distance */
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(21, g, 200.0);
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(22, g, 200.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakePoint2d(306, g, 200, 21, 22);
|
||||||
|
|
||||||
|
sys.param[sys.params++] = Slvs_MakeParam(23, g, 30.0);
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakeDistance(307, g, 200, 23);
|
||||||
|
|
||||||
|
/* And a complete circle, centered at point 306 with radius equal to
|
||||||
|
* distance 307. The normal is 102, the same as our workplane. */
|
||||||
|
sys.entity[sys.entities++] = Slvs_MakeCircle(402, g, 200,
|
||||||
|
306, 102, 307);
|
||||||
|
|
||||||
|
|
||||||
|
/* The length of our line segment is 30.0 units. */
|
||||||
|
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||||
|
1, g,
|
||||||
|
SLVS_C_PT_PT_DISTANCE,
|
||||||
|
200,
|
||||||
|
30.0,
|
||||||
|
301, 302, 0, 0);
|
||||||
|
|
||||||
|
/* And the distance from our line segment to the origin is 10.0 units. */
|
||||||
|
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||||
|
2, g,
|
||||||
|
SLVS_C_PT_LINE_DISTANCE,
|
||||||
|
200,
|
||||||
|
10.0,
|
||||||
|
101, 0, 400, 0);
|
||||||
|
/* And the line segment is vertical. */
|
||||||
|
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||||
|
3, g,
|
||||||
|
SLVS_C_VERTICAL,
|
||||||
|
200,
|
||||||
|
0.0,
|
||||||
|
0, 0, 400, 0);
|
||||||
|
/* And the distance from one endpoint to the origin is 15.0 units. */
|
||||||
|
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||||
|
4, g,
|
||||||
|
SLVS_C_PT_PT_DISTANCE,
|
||||||
|
200,
|
||||||
|
15.0,
|
||||||
|
301, 101, 0, 0);
|
||||||
|
#if 0
|
||||||
|
/* And same for the other endpoint; so if you add this constraint then
|
||||||
|
* the sketch is overconstrained and will signal an error. */
|
||||||
|
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||||
|
5, g,
|
||||||
|
SLVS_C_PT_PT_DISTANCE,
|
||||||
|
200,
|
||||||
|
18.0,
|
||||||
|
302, 101, 0, 0);
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
|
/* The arc and the circle have equal radius. */
|
||||||
|
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||||
|
6, g,
|
||||||
|
SLVS_C_EQUAL_RADIUS,
|
||||||
|
200,
|
||||||
|
0.0,
|
||||||
|
0, 0, 401, 402);
|
||||||
|
/* The arc has radius 17.0 units. */
|
||||||
|
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||||
|
7, g,
|
||||||
|
SLVS_C_DIAMETER,
|
||||||
|
200,
|
||||||
|
17.0*2,
|
||||||
|
0, 0, 401, 0);
|
||||||
|
|
||||||
|
/* If the solver fails, then ask it to report which constraints caused
|
||||||
|
* the problem. */
|
||||||
|
sys.calculateFaileds = 1;
|
||||||
|
|
||||||
|
/* And solve. */
|
||||||
|
Slvs_Solve(&sys, g);
|
||||||
|
|
||||||
|
if(sys.result == SLVS_RESULT_OKAY) {
|
||||||
|
printf("solved okay\n");
|
||||||
|
printf("line from (%.3f %.3f) to (%.3f %.3f)\n",
|
||||||
|
sys.param[7].val, sys.param[8].val,
|
||||||
|
sys.param[9].val, sys.param[10].val);
|
||||||
|
|
||||||
|
printf("arc center (%.3f %.3f) start (%.3f %.3f) finish (%.3f %.3f)\n",
|
||||||
|
sys.param[11].val, sys.param[12].val,
|
||||||
|
sys.param[13].val, sys.param[14].val,
|
||||||
|
sys.param[15].val, sys.param[16].val);
|
||||||
|
|
||||||
|
printf("circle center (%.3f %.3f) radius %.3f\n",
|
||||||
|
sys.param[17].val, sys.param[18].val,
|
||||||
|
sys.param[19].val);
|
||||||
|
printf("%d DOF\n", sys.dof);
|
||||||
|
} else {
|
||||||
|
int i;
|
||||||
|
printf("solve failed: problematic constraints are:");
|
||||||
|
for(i = 0; i < sys.faileds; i++) {
|
||||||
|
printf(" %d", sys.failed[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
if(sys.result == SLVS_RESULT_INCONSISTENT) {
|
||||||
|
printf("system inconsistent\n");
|
||||||
|
} else {
|
||||||
|
printf("system nonconvergent\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int solver(float *ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Example2d(150.0);
|
||||||
|
// sys.params = sys.constraints = sys.entities = 0;
|
||||||
|
for (int i=0; i<10 ;i++) {
|
||||||
|
printf("%f\n",*ptr++);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
sys.param = CheckMalloc(50*sizeof(sys.param[0]));
|
||||||
|
sys.entity = CheckMalloc(50*sizeof(sys.entity[0]));
|
||||||
|
sys.constraint = CheckMalloc(50*sizeof(sys.constraint[0]));
|
||||||
|
|
||||||
|
sys.failed = CheckMalloc(50*sizeof(sys.failed[0]));
|
||||||
|
sys.faileds = 50;
|
||||||
|
|
||||||
|
|
||||||
|
// Example2d(150.0);
|
||||||
|
|
||||||
|
printf("hello\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue