mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-07 13:57:48 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
#include "../sg.h"
|
||||
|
||||
//
|
||||
|
||||
static GEO_ARC geo_arc; // . /
|
||||
static ARC_TYPE geo_flag = ECS_NOT_DEF; // ARC_TYPE
|
||||
static MATR ecs_gcs_arc; // . .
|
||||
static MATR gcs_ecs_arc; // . .
|
||||
|
||||
//--- /
|
||||
void get_curr_ecs_arc(lpGEO_ARC arc, lpARC_TYPE flag)
|
||||
{
|
||||
|
||||
*flag = geo_flag;
|
||||
if (geo_flag == ECS_NOT_DEF) return;
|
||||
memcpy(arc, &geo_arc,
|
||||
((geo_flag) ? sizeof(GEO_ARC) : sizeof(GEO_CIRCLE)));
|
||||
}
|
||||
/*--- /
|
||||
|
||||
arc - /
|
||||
flag -
|
||||
*/
|
||||
void init_ecs_arc(lpGEO_ARC arc, ARC_TYPE flag)
|
||||
{
|
||||
D_POINT p;
|
||||
int l;
|
||||
|
||||
if (flag == ECS_NOT_DEF) return;
|
||||
p.x = - arc->vc.x;
|
||||
p.y = - arc->vc.y;
|
||||
p.z = - arc->vc.z;
|
||||
o_hcunit(gcs_ecs_arc);
|
||||
o_tdtran(gcs_ecs_arc, &p);
|
||||
o_hcrot1(gcs_ecs_arc, &arc->n);
|
||||
o_minv(gcs_ecs_arc, ecs_gcs_arc);
|
||||
l = (flag == ECS_ARC) ? sizeof(GEO_ARC) : sizeof(GEO_CIRCLE);
|
||||
memcpy(&geo_arc, arc, l);
|
||||
geo_flag = flag;
|
||||
if (flag == ECS_CIRCLE) {
|
||||
geo_arc.ab = 0;
|
||||
geo_arc.angle = 2 * M_PI;
|
||||
p.x = arc->r;
|
||||
p.y = p.z = 0;
|
||||
ecs_to_gcs(&p, &geo_arc.vb);
|
||||
memcpy(&geo_arc.ve, &geo_arc.vb, sizeof(D_POINT));
|
||||
}
|
||||
}
|
||||
|
||||
//--- .
|
||||
void ecs_to_gcs(lpD_POINT from, lpD_POINT to)
|
||||
{
|
||||
o_hcncrd(ecs_gcs_arc, from, to);
|
||||
}
|
||||
|
||||
//--- .
|
||||
void gcs_to_ecs(lpD_POINT from, lpD_POINT to)
|
||||
{
|
||||
o_hcncrd(gcs_ecs_arc, from, to);
|
||||
}
|
||||
|
||||
//--- . ./
|
||||
void get_point_on_arc(sgFloat alpha, lpD_POINT p)
|
||||
{
|
||||
sgFloat an;
|
||||
D_POINT tmp;
|
||||
|
||||
if (alpha <= 0.)
|
||||
memcpy(p, &geo_arc.vb, sizeof(D_POINT));
|
||||
else if (alpha >= 1.)
|
||||
memcpy(p, &geo_arc.ve, sizeof(D_POINT));
|
||||
else {
|
||||
an = geo_arc.ab + alpha * geo_arc.angle;
|
||||
tmp.x = geo_arc.r * cos(an);
|
||||
tmp.y = geo_arc.r * sin(an);
|
||||
tmp.z = 0;
|
||||
ecs_to_gcs(&tmp, p);
|
||||
}
|
||||
}
|
||||
|
||||
//--- ,
|
||||
CODE_MSG arc_init(ARC_INIT_REGIM regim, lpD_POINT p, lpGEO_ARC arc)
|
||||
{
|
||||
D_POINT pp;
|
||||
sgFloat dist;
|
||||
CODE_MSG code;
|
||||
|
||||
switch (regim) {
|
||||
case ARC_CENTER:
|
||||
memcpy(&arc->vc, p, sizeof(D_POINT));
|
||||
break;
|
||||
case ARC_BEGIN:
|
||||
if ((code = circle_init((lpGEO_CIRCLE)arc, p)) != EMPTY_MSG)
|
||||
return code;
|
||||
memcpy(&arc->vb, p, sizeof(D_POINT));
|
||||
break;
|
||||
case ARC_END:
|
||||
if (fabs(dskalar_product(&arc->n, dpoint_sub(p, &arc->vc, &pp))
|
||||
) > eps_d) return POINT_NOT_ON_CIRCLE_PLANE;
|
||||
if (fabs(dist = dpoint_distance(&arc->vc, p)) < eps_d) {
|
||||
return ARC_ANGLE_ZERO;
|
||||
}
|
||||
dpoint_parametr(&arc->vc, p, arc->r / dist, &arc->ve);
|
||||
calc_arc_angle(arc);
|
||||
// if (dskalar_product(&arc->n,&curr_w3->from) < 0.)
|
||||
// arc->angle -= 2 * M_PI;
|
||||
break;
|
||||
}
|
||||
return EMPTY_MSG;
|
||||
}
|
||||
|
||||
/*--- , , ,
|
||||
|
||||
*/
|
||||
void calc_arc_ab(lpGEO_ARC arc)
|
||||
{
|
||||
D_POINT v1;
|
||||
|
||||
init_ecs_arc(arc,ECS_ARC);
|
||||
gcs_to_ecs(&arc->vb,&v1);
|
||||
arc->ab = atan2(v1.y, v1.x);
|
||||
if (arc->ab < 0.) arc->ab += 2 * M_PI;
|
||||
}
|
||||
|
||||
void calc_arc_angle(lpGEO_ARC arc)
|
||||
{
|
||||
D_POINT pp;
|
||||
|
||||
calc_arc_ab(arc);
|
||||
gcs_to_ecs(&arc->ve,&pp);
|
||||
arc->angle = atan2(pp.y, pp.x);
|
||||
if (arc->angle < 0.) arc->angle += 2 * M_PI;
|
||||
if (arc->angle < arc->ab) arc->angle += 2 * M_PI;
|
||||
arc->angle -= arc->ab;
|
||||
}
|
||||
|
||||
//---
|
||||
extern BOOL super_flag;
|
||||
extern D_POINT super_normal, super_origin;
|
||||
void normal_cpl(lpD_POINT n)
|
||||
{
|
||||
if (super_flag) {
|
||||
*n = super_normal;
|
||||
} else {
|
||||
DA_POINT p1 = {0,0,0};
|
||||
D_POINT p0 = {0,0,0}, pp0, pp1;
|
||||
int axis = get_index_invalid_axis();
|
||||
|
||||
p1[axis] = 1;
|
||||
dpoint_sub(&pp1, &pp0, n);
|
||||
}
|
||||
// cpl_vport[curr_vp].n = *n;
|
||||
}
|
||||
|
||||
/*---
|
||||
.. circle->vc
|
||||
p -
|
||||
EMPTY_MSG, cicrle->r circle->n
|
||||
|
||||
!
|
||||
*/
|
||||
CODE_MSG circle_init(lpGEO_CIRCLE circle, lpD_POINT p)
|
||||
{
|
||||
D_POINT pp;
|
||||
|
||||
normal_cpl(&circle->n);
|
||||
circle->r = 0;
|
||||
if (fabs(dskalar_product(&circle->n, dpoint_sub(p, &circle->vc, &pp))
|
||||
) > eps_d) return POINT_NOT_ON_CIRCLE_PLANE;
|
||||
circle->r = dpoint_distance(p, &circle->vc);
|
||||
if (circle->r < eps_d) return RADIUS_ZERO;
|
||||
return EMPTY_MSG;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "../sg.h"
|
||||
/*---
|
||||
objects,
|
||||
,
|
||||
|
||||
|
||||
*/
|
||||
BOOL no_attach_and_regen(hOBJ hobj)
|
||||
{
|
||||
D_POINT min, max;
|
||||
|
||||
if (!get_object_limits(hobj,&min,&max)) return FALSE;
|
||||
modify_limits(&min, &max);
|
||||
return TRUE;//vi_regen(hobj,get_regim_edge() | get_switch_display());
|
||||
}
|
||||
BOOL attach_and_regen(hOBJ hobj)
|
||||
{
|
||||
if (objects.num==0)
|
||||
{
|
||||
scene_min.x = scene_min.y = scene_min.z = GAB_NO_DEF;
|
||||
scene_max.x = scene_max.y = scene_max.z = -GAB_NO_DEF;
|
||||
}
|
||||
attach_item_tail(&objects,hobj);
|
||||
return no_attach_and_regen(hobj);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#include "../sg.h"
|
||||
|
||||
hOBJ create_simple_obj_loc(OBJTYPE type, void *geo)
|
||||
{
|
||||
// .
|
||||
hOBJ hobj;
|
||||
lpOBJ obj;
|
||||
|
||||
if((hobj = o_alloc(type)) == NULL)
|
||||
return NULL;
|
||||
obj = (lpOBJ)hobj;
|
||||
//set_obj_nongeo_par(obj);
|
||||
memcpy(obj->geo_data, geo, geo_size[type]);
|
||||
return hobj;
|
||||
}
|
||||
|
||||
hOBJ create_simple_obj(OBJTYPE type, void *geo) {
|
||||
// , ..
|
||||
// : type -
|
||||
// geo -
|
||||
// .
|
||||
//
|
||||
|
||||
// NULL,
|
||||
//
|
||||
|
||||
return create_simple_obj_to_prot(NULL, type, geo);
|
||||
}
|
||||
|
||||
hOBJ create_simple_obj_to_prot(lpOBJ prot, OBJTYPE type, void *geo) {
|
||||
// ,
|
||||
|
||||
hOBJ hobj;
|
||||
lpOBJ obj;
|
||||
|
||||
if((hobj = o_alloc(type)) == NULL)
|
||||
return NULL;
|
||||
obj = (lpOBJ)hobj;
|
||||
if(prot)
|
||||
copy_obj_nongeo_par(prot, obj);
|
||||
else{
|
||||
set_obj_nongeo_par(obj);
|
||||
fc_assign_curr_ident(hobj);
|
||||
}
|
||||
|
||||
memcpy(obj->geo_data, geo, geo_size[type]);
|
||||
|
||||
if(!prot)
|
||||
attach_and_regen(hobj);
|
||||
return hobj;
|
||||
}
|
||||
|
||||
void set_obj_nongeo_par(lpOBJ obj){
|
||||
if(check_type(struct_filter, obj->type) && obj_attrib.flg_transp )
|
||||
obj->color = CTRANSP;
|
||||
else
|
||||
obj->color = obj_attrib.color;
|
||||
obj->layer = obj_attrib.layer;
|
||||
obj->ltype = obj_attrib.ltype;
|
||||
obj->lthickness = obj_attrib.lthickness;
|
||||
}
|
||||
|
||||
void copy_obj_nongeo_par(lpOBJ prot, lpOBJ obj){
|
||||
obj->layer = prot->layer;
|
||||
obj->color = prot->color;
|
||||
obj->drawstatus = prot->drawstatus;
|
||||
obj->status = prot->status;
|
||||
obj->ltype = prot->ltype;
|
||||
obj->lthickness = prot->lthickness;
|
||||
}
|
||||
|
||||
OBJTYPE get_simple_obj_geo(hOBJ hobj, void *geo) {
|
||||
// .
|
||||
// hobj -
|
||||
// :
|
||||
// geo -
|
||||
// .
|
||||
|
||||
lpOBJ obj;
|
||||
OBJTYPE type;
|
||||
|
||||
obj = (lpOBJ)hobj;
|
||||
type = obj->type;
|
||||
memcpy(geo, obj->geo_data, geo_size[type]);
|
||||
return type;
|
||||
}
|
||||
|
||||
void get_simple_obj(hOBJ hobj, lpOBJ nongeo, void *geo) {
|
||||
//
|
||||
|
||||
lpOBJ obj;
|
||||
|
||||
obj = (lpOBJ)hobj;
|
||||
memcpy(nongeo, obj, sizeof(OBJ));
|
||||
memcpy(geo, obj->geo_data, geo_size[obj->type]);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "../sg.h"
|
||||
#include "../common_hdr.h"
|
||||
|
||||
static char LastBakPathName[MAXPATH];
|
||||
|
||||
//
|
||||
bool CreateBakFile(char *pathname)
|
||||
{
|
||||
char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT],
|
||||
ext2[MAXEXT];
|
||||
|
||||
fnsplit(pathname, drive, dir, file, ext);
|
||||
strcpy(ext2, ".~");
|
||||
if (strlen(ext) > 0) strncat(ext2, &ext[1], 2);
|
||||
fnmerge(LastBakPathName, drive, dir, file, ext2);
|
||||
if (!nb_access(LastBakPathName, 0)) {
|
||||
// :
|
||||
nb_unlink(LastBakPathName);
|
||||
}
|
||||
if (nb_rename(pathname, LastBakPathName)) {
|
||||
LastBakPathName[0] = 0;
|
||||
put_message(IDS_SG259, pathname, 0);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void RestoreFromBakFile(char *pathname)
|
||||
//
|
||||
{
|
||||
if(LastBakPathName[0])
|
||||
if(!nb_access(LastBakPathName, 0))
|
||||
nb_rename(LastBakPathName, pathname);
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
#include "../sg.h"
|
||||
/*
|
||||
OX OY
|
||||
|
||||
*/
|
||||
void lcs_oxy(lpD_POINT p0, lpD_POINT px, lpD_POINT py, MATR m)
|
||||
{
|
||||
D_POINT x, y, z;
|
||||
|
||||
m[3] = p0->x; m[7] = p0->y; m[11] = p0->z; m[15] = 1;
|
||||
dnormal_vector(dpoint_sub(px, p0, &x));
|
||||
dnormal_vector(dpoint_sub(py, p0, &y));
|
||||
dnormal_vector(dvector_product(&x, &y, &z));
|
||||
m[0] = x.x; m[1] = y.x; m[ 2] = z.x;
|
||||
m[4] = x.y; m[5] = y.y; m[ 6] = z.y;
|
||||
m[8] = x.z; m[9] = y.z; m[10] = z.z;
|
||||
m[12] = m[13] = m[14] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
-> ,
|
||||
, - XOY || .
|
||||
*/
|
||||
void lcs_cpl_bp(MATR m)
|
||||
{
|
||||
D_POINT n, p;
|
||||
|
||||
normal_cpl(&n);
|
||||
o_hcunit(m);
|
||||
o_tdtran(m, dpoint_inv(&curr_point, &p));
|
||||
o_hcrot1(m, &n);
|
||||
o_minv(m, m);
|
||||
}
|
||||
|
||||
/*
|
||||
-> ,
|
||||
, OZ || n
|
||||
*/
|
||||
void lcs_normal_bp(MATR m, lpD_POINT n)
|
||||
{
|
||||
D_POINT p;
|
||||
|
||||
o_hcunit(m);
|
||||
o_tdtran(m, dpoint_inv(&curr_point, &p));
|
||||
o_hcrot1(m, n);
|
||||
o_minv(m, m);
|
||||
}
|
||||
|
||||
/*
|
||||
: rez_geo.m[0]: ->
|
||||
p1 -
|
||||
*/
|
||||
void box_fixed_lsk(lpD_POINT p1)
|
||||
{
|
||||
MATR mi;
|
||||
D_POINT pp1;
|
||||
|
||||
matr_gcs_to_default_cs(rez_geo.m[0]);
|
||||
o_hcncrd(rez_geo.m[0], p1, &pp1);
|
||||
matr_default_cs_to_gcs(mi);
|
||||
o_hcunit(rez_geo.m[0]);
|
||||
o_tdtran(rez_geo.m[0], &pp1);
|
||||
o_hcmult(rez_geo.m[0], mi); // rez_geo.m[0]: ->
|
||||
}
|
||||
|
||||
/*--- ,
|
||||
, p0,
|
||||
pz OZ. (
|
||||
OX OY " ")
|
||||
*/
|
||||
void lcs_axis_z(lpD_POINT p0, lpD_POINT pz, MATR m)
|
||||
{
|
||||
D_POINT p;
|
||||
|
||||
o_hcunit(m);
|
||||
o_hcrot1(m, dpoint_sub(pz, p0, &p));
|
||||
o_minv(m, m);
|
||||
o_tdtran(m, p0);
|
||||
}
|
||||
|
||||
/*--- ,
|
||||
, p0,
|
||||
OX p0 px
|
||||
-
|
||||
p0 px .
|
||||
*/
|
||||
void lcs_o_px(lpD_POINT p0, lpD_POINT px, MATR m)
|
||||
{
|
||||
D_POINT pp0, ppx, ppy;
|
||||
sgFloat a, b, c;
|
||||
|
||||
gcs_to_vcs(p0, &pp0);
|
||||
gcs_to_vcs(px, &ppx);
|
||||
ppx.z = pp0.z;
|
||||
if (!eq_line(&pp0, &ppx, &a, &b, &c)) {
|
||||
o_hcunit(m);
|
||||
return;
|
||||
}
|
||||
ppy.x = pp0.x + a;
|
||||
ppy.y = pp0.y + b;
|
||||
ppy.z = pp0.z;
|
||||
vcs_to_gcs(&ppx, &ppx);
|
||||
vcs_to_gcs(&ppy, &ppy);
|
||||
lcs_oxy(p0, &ppx, &ppy, m);
|
||||
}
|
||||
|
||||
//
|
||||
void matr_default_cs_to_gcs(MATR matr)
|
||||
{
|
||||
// switch (CURR_TYPE_CS) {
|
||||
// case CS_VIEW:
|
||||
//memcpy(matr, curr_w3->matri, sizeof(MATR));
|
||||
// break;
|
||||
// case CS_USER:
|
||||
memcpy(matr, m_ucs_gcs, sizeof(MATR));
|
||||
// break;
|
||||
// default:
|
||||
// o_hcunit(matr);
|
||||
// break;
|
||||
//}
|
||||
}
|
||||
|
||||
//
|
||||
void matr_gcs_to_default_cs(MATR matr)
|
||||
{
|
||||
// switch (CURR_TYPE_CS) {
|
||||
// case CS_VIEW:
|
||||
//memcpy(matr, curr_w3->matrp, sizeof(MATR));
|
||||
// break;
|
||||
// case CS_USER:
|
||||
memcpy(matr, m_gcs_ucs, sizeof(MATR));
|
||||
// break;
|
||||
// default:
|
||||
// o_hcunit(matr);
|
||||
// break;
|
||||
//}
|
||||
}
|
||||
|
||||
// (0-x, 1-y, 2-z)
|
||||
short get_index_invalid_axis(void)
|
||||
{
|
||||
D_POINT p0 = {0,0,0}, p1 = {0,0,1}, p2, p3;
|
||||
sgFloat d, d1, angle = 10;
|
||||
|
||||
gcs_to_vcs(&p0, &p0);
|
||||
gcs_to_vcs(&p2, &p2);
|
||||
dpoint_sub(&p2, &p0, &p3);
|
||||
dnormal_vector(&p3);
|
||||
d = dskalar_product(&p3, &p1);
|
||||
d = fabs(90 - d_degree(acos(d)));
|
||||
if (d > angle) return 2; // XOY
|
||||
p2.x = 1; p2.y = 0; p2.z = 0;
|
||||
gcs_to_vcs(&p2, &p2);
|
||||
dpoint_sub(&p2, &p0, &p3);
|
||||
dnormal_vector(&p3);
|
||||
d = dskalar_product(&p3, &p1);
|
||||
d1 = fabs(90 - d_degree(acos(d)));
|
||||
p2.x = 0; p2.y = 1; p2.z = 0;
|
||||
gcs_to_vcs(&p2, &p2);
|
||||
dpoint_sub(&p2, &p0, &p3);
|
||||
dnormal_vector(&p3);
|
||||
d = dskalar_product(&p3, &p1);
|
||||
d = fabs(90 - d_degree(acos(d)));
|
||||
if (d1 > d) return 0; // YOZ
|
||||
return 1; // ZOX
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "../sg.h"
|
||||
|
||||
//
|
||||
|
||||
D_POINT curr_point ={0., 0., 0.}, curr_point_vcs;
|
||||
|
||||
void set_curr_point(lpD_POINT p){ //
|
||||
|
||||
memcpy(&curr_point, p, sizeof(D_POINT));
|
||||
gcs_to_vcs(&curr_point, &curr_point_vcs);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "../sg.h"
|
||||
|
||||
void delete_obj(hOBJ hobj){
|
||||
//
|
||||
//
|
||||
detach_item_z(OBJ_LIST,&objects,hobj); //
|
||||
// free_viobj_scan(hobj); //
|
||||
// undo_to_delete(hobj); //
|
||||
SetModifyFlag(TRUE); // .
|
||||
}
|
||||
|
||||
void autodelete_obj(hOBJ hobj){
|
||||
//draw_obj(hobj,vport_bg);
|
||||
delete_obj(hobj);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "../sg.h"
|
||||
|
||||
short floating_precision = 3; //
|
||||
short export_floating_precision = 7; //
|
||||
|
||||
|
||||
char *sgFloat_to_text(sgFloat d, BOOL delspace, char *txt){
|
||||
// sgFloat
|
||||
// . delspace = TRUE -
|
||||
//
|
||||
|
||||
return sgFloat_output(d, LEN_sgFloat, floating_precision, delspace, TRUE, txt);
|
||||
}
|
||||
|
||||
char *sgFloat_to_textf(sgFloat d, short size, short precision, char *txt){
|
||||
// sgFloat .
|
||||
return sgFloat_output(d, size, precision, FALSE, TRUE, txt);
|
||||
}
|
||||
|
||||
char *dummy_to_text(char *txt){
|
||||
short l = LEN_sgFloat;
|
||||
// -
|
||||
memset(txt, '*', l);
|
||||
txt[l] = 0;
|
||||
if(l > 2) txt[0] = txt[1] = ' ';
|
||||
if(l > 5) txt[l - 1] = txt[l - 2] = ' ';
|
||||
return txt;
|
||||
}
|
||||
|
||||
void sgFloat_to_text_for_export(char *buf, sgFloat num)
|
||||
// DXF
|
||||
{
|
||||
sgFloat_output1(num, -1, export_floating_precision, TRUE, FALSE,TRUE, buf);
|
||||
}
|
||||
|
||||
char *sgFloat_to_textp(sgFloat num, char *buf){
|
||||
// ,
|
||||
// , ,
|
||||
//
|
||||
// buf MAX_sgFloat_STRING
|
||||
return sgFloat_output(num, -1, floating_precision, TRUE, TRUE, buf);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "../sg.h"
|
||||
|
||||
/*
|
||||
� © ¯®¥ª ®ª p ¯¬, ¯®®¤ ¥¥§ ®ª l1,l2
|
||||
|
||||
‚®§¢ ¥: NULL - ¥« ®ª l1,l2 ®¢¯ ¤
|
||||
‘®®¡¥¥ ¥ ¢¤ ¥!
|
||||
«ª ª®¬ ®ª - ¢ ®¬ «®¬ « ¥
|
||||
Œ¥®¤:
|
||||
ª®¬ ®ª ®¤ § ¥¥ ¥¬ § 4- «.-©:
|
||||
pp = l1 + alpha * (l2 - l1) - pp «¥¦ ¯¬®©
|
||||
(p - pp, l2 - l1) = 0 - ª «®¥ ¯®§¢. = 0
|
||||
*/
|
||||
lpD_POINT projection_on_line(lpD_POINT p,
|
||||
lpD_POINT l1, lpD_POINT l2,
|
||||
lpD_POINT pp)
|
||||
{
|
||||
D_POINT ll;
|
||||
sgFloat alpha;
|
||||
|
||||
dpoint_sub(l2, l1, &ll);
|
||||
alpha = dskalar_product(&ll, &ll);
|
||||
if (alpha < eps_d) return NULL;
|
||||
alpha = (dskalar_product(&ll, p) - dskalar_product(&ll, l1)) / alpha;
|
||||
return dpoint_parametr(l1, l2, alpha, pp);
|
||||
}
|
||||
|
||||
/*
|
||||
‚« ¢¥ p2 p3 ¯¬®£®«ª ¯® § ¤ ¬ ¢¥ ¬
|
||||
p0, p1 ¯® ¢¥¥, «¥¦ ¥© ¯¬®© p2,p3.
|
||||
‚®§¬®¦ ¢®¦¤¥® ¯¬®£®«ª ¢ ®¥§®ª p0,p1.
|
||||
|
||||
‚®§¢ ¥: TRUE - ¢¥ p2,p3 ¢«¥
|
||||
FALSE - ¯¬®£®«ª ¢®¦¤¥ ¢ ®¥§®ª p0,p1 «
|
||||
®¥§®ª p0,p1 ¬¥¥ «¥¢ ¤«
|
||||
‘®®¡¥¥ ¥ ¢¤ ¥!
|
||||
*/
|
||||
BOOL calc_face4(lpD_POINT p0, lpD_POINT p1, lpD_POINT p,
|
||||
lpD_POINT p2, lpD_POINT p3)
|
||||
{
|
||||
D_POINT pp, a;
|
||||
|
||||
if (!projection_on_line(p, p0, p1, &pp)) return FALSE;
|
||||
dpoint_sub(p, &pp, &a);
|
||||
dpoint_add(p0, &a, p2);
|
||||
dpoint_add(p1, &a, p3);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "../sg.h"
|
||||
|
||||
void union_limits(lpD_POINT mn1, lpD_POINT mx1,
|
||||
lpD_POINT mn2, lpD_POINT mx2)
|
||||
{
|
||||
mn2->x = min(mn1->x, mn2->x);
|
||||
mn2->y = min(mn1->y, mn2->y);
|
||||
mn2->z = min(mn1->z, mn2->z);
|
||||
mx2->x = max(mx1->x, mx2->x);
|
||||
mx2->y = max(mx1->y, mx2->y);
|
||||
mx2->z = max(mx1->z, mx2->z);
|
||||
}
|
||||
|
||||
//---
|
||||
BOOL get_scene_limits(void)
|
||||
{
|
||||
hOBJ hobj = objects.hhead;
|
||||
D_POINT min, max;
|
||||
BOOL ret;
|
||||
lpOBJ obj;
|
||||
ODRAWSTATUS st;
|
||||
|
||||
scene_min.x = scene_min.y = scene_min.z = GAB_NO_DEF;
|
||||
scene_max.x = scene_max.y = scene_max.z = -GAB_NO_DEF;
|
||||
while (hobj) {
|
||||
obj = (lpOBJ)hobj;
|
||||
st = obj->drawstatus;
|
||||
if (!(st & ST_HIDE)) {
|
||||
if (!(ret = get_object_limits(hobj,&min,&max))) break;
|
||||
union_limits(&min,&max,&scene_min,&scene_max);
|
||||
}
|
||||
get_next_item(hobj,&hobj);
|
||||
}
|
||||
if (scene_min.x == GAB_NO_DEF) {
|
||||
scene_min.x = scene_min.y = scene_min.z = -100;
|
||||
scene_max.x = scene_max.y = scene_max.z = 100;
|
||||
ret = TRUE;
|
||||
}
|
||||
if (fabs(scene_min.x - scene_max.x) < eps_d) {
|
||||
scene_min.x -= 100 * eps_d;
|
||||
scene_max.x += 100 * eps_d;
|
||||
}
|
||||
if (fabs(scene_min.y - scene_max.y) < eps_d) {
|
||||
scene_min.y -= 100 * eps_d;
|
||||
scene_max.y += 100 * eps_d;
|
||||
}
|
||||
if (fabs(scene_min.z - scene_max.z) < eps_d) {
|
||||
scene_min.z -= 100 * eps_d;
|
||||
scene_max.z += 100 * eps_d;
|
||||
}
|
||||
define_eps(&scene_min, &scene_max);
|
||||
return ret;
|
||||
}
|
||||
//---
|
||||
void modify_limits(lpD_POINT min, lpD_POINT max)
|
||||
{
|
||||
// sgFloat dx, dy, dz;
|
||||
|
||||
if (min->x != GAB_NO_DEF) {
|
||||
union_limits(min,max,&scene_min,&scene_max);
|
||||
define_eps(&scene_min, &scene_max);
|
||||
/*if (!limits_tog) {
|
||||
limits_min = scene_min;
|
||||
limits_max = scene_max;
|
||||
dx = (limits_max.x - limits_min.x);// * MARGIN_VPORT;
|
||||
dy = (limits_max.y - limits_min.y);// * MARGIN_VPORT;
|
||||
dz = (limits_max.z - limits_min.z);// * MARGIN_VPORT;
|
||||
limits_min.x -= dx; limits_max.x += dx;
|
||||
limits_min.y -= dy; limits_max.y += dy;
|
||||
limits_min.z -= dz; limits_max.z += dz;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "../sg.h"
|
||||
|
||||
//
|
||||
lpSTATIC_DATA static_data = NULL; //
|
||||
|
||||
short sg_m_num_meridians = 24; // -
|
||||
|
||||
LISTH objects; // .
|
||||
LISTH selected; //
|
||||
|
||||
// ,
|
||||
short curr_color = IDXBLUE; //
|
||||
UCHAR vport_bg = IDXLIGHTGRAY; //
|
||||
|
||||
UCHAR screen_color = IDXBLACK; //
|
||||
|
||||
//===
|
||||
D_POINT scene_min = { 100, 100, 100}, // .
|
||||
scene_max = {-100,-100,-100}; // ..
|
||||
UCHAR message_level = 3; //
|
||||
|
||||
MATR m_ucs_gcs, m_gcs_ucs; //
|
||||
|
||||
BOOL super_flag = FALSE;
|
||||
D_POINT super_normal, super_origin;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "../sg.h"
|
||||
|
||||
void detach_all_group_obj(hOBJ hgroup, BOOL undoflag){
|
||||
// ‚ ¢¥ ®¡¥ª § £¯¯
|
||||
|
||||
lpOBJ obj;
|
||||
hOBJ hobj, hnext;
|
||||
lpGEO_GROUP geo;
|
||||
LISTH group;
|
||||
OBJTYPE type;
|
||||
ODRAWSTATUS dstatus;
|
||||
OSCAN_COD regen;
|
||||
|
||||
obj = (lpOBJ)hgroup;
|
||||
type = obj->type;
|
||||
dstatus = obj->drawstatus & ST_TD_BOX;
|
||||
geo = (lpGEO_GROUP)obj->geo_data;
|
||||
memcpy(&group, &geo->listh, sizeof(LISTH));
|
||||
init_listh(&geo->listh);
|
||||
|
||||
if (dstatus) {
|
||||
//draw_obj(hgroup, vport_bg);
|
||||
;//free_viobj(hgroup);
|
||||
}
|
||||
|
||||
hobj = group.hhead;
|
||||
regen = OSTRUE;
|
||||
while (hobj) {
|
||||
get_next_item_z(OBJ_LIST, hobj, &hnext);
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->hhold = NULL;
|
||||
if (type == OPATH) {
|
||||
obj->status &= (~ST_DIRECT);
|
||||
obj->status &= ~(ST_CONSTR1 | ST_CONSTR2);
|
||||
}
|
||||
attach_item_tail_z(OBJ_LIST, &objects, hobj);
|
||||
if (dstatus) {
|
||||
//if (regen == OSTRUE || regen == OSSKIP)
|
||||
// regen = vi_regen(hobj, get_regim_edge() | get_switch_display());
|
||||
} else {
|
||||
// change_viobj_color(hobj, COBJ);
|
||||
;//draw_obj(hobj, CDEFAULT);
|
||||
}
|
||||
//if(undoflag)
|
||||
// undo_to_one_remove(hobj);
|
||||
hobj = hnext;
|
||||
}
|
||||
}
|
||||
|
||||
void attach_obj_to_group(hOBJ hgroup, hOBJ hobj){
|
||||
// �®§¢¥ ¤¥¢ ¯ ¤®¡ ¢«¥ ®¡¥ª ¢ £¯¯
|
||||
lpOBJ obj;
|
||||
|
||||
detach_item_z(OBJ_LIST, &objects, hobj);
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->status &= (~(ST_SELECT|ST_BLINK));
|
||||
obj->hhold = hgroup; // ‘«ª ®¡¥ª ¢¥¥£® ®¢
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
#include "../sg.h"
|
||||
|
||||
//
|
||||
char* GetObjTypeCaption(OBJTYPE type, char* str, int len)
|
||||
{
|
||||
/* LoadString(hInstLD, GetObjMethod(type, OMT_OBJTYPE_CAPTION), str, len - 1);
|
||||
str[len - 1] = 0;
|
||||
return str;*/return NULL;
|
||||
}
|
||||
|
||||
// .
|
||||
// - . - ..
|
||||
// BREP - , ,
|
||||
char* GetObjDescriptionStr(char* str, int len, hOBJ hobj)
|
||||
{
|
||||
lpOBJ obj;
|
||||
OBJTYPE type;
|
||||
void (*fstr)(hOBJ hobj, char *str, int len);
|
||||
|
||||
obj = (lpOBJ)hobj;
|
||||
type = obj->type;
|
||||
fstr = (void (*)(hOBJ hobj, char *str, int len))GetObjMethod(type, OMT_OBJ_DESCRIPT);
|
||||
if(!fstr)
|
||||
return GetObjTypeCaption(type, str, len);
|
||||
fstr(hobj, str, len);
|
||||
return str;
|
||||
}
|
||||
|
||||
void IdleObjDecriptStr(hOBJ hobj, char *str, int len)
|
||||
//
|
||||
{
|
||||
GetObjTypeCaption(((lpOBJ)hobj)->type, str, len);
|
||||
}
|
||||
|
||||
void ot_brep_str(hOBJ hobj, char *str, int len)
|
||||
{
|
||||
CODE_MSG cod;
|
||||
lpGEO_BREP geo;
|
||||
lpOBJ obj;
|
||||
LNP lnp;
|
||||
int num;
|
||||
BREPTYPE type;
|
||||
|
||||
|
||||
obj = (lpOBJ)hobj;
|
||||
geo = (lpGEO_BREP)(obj->geo_data);
|
||||
num = geo->num;
|
||||
type = (BREPTYPE)geo->type;
|
||||
if ( !(read_elem(&vd_brep,num,&lnp)) ) return;
|
||||
switch ( lnp.kind ) {
|
||||
case COMMON:
|
||||
switch(type){
|
||||
case BODY:
|
||||
cod = BRBODY_MSG;
|
||||
break;
|
||||
case SURF:
|
||||
cod = BRSURF_MSG;
|
||||
break;
|
||||
default:
|
||||
cod = BRFRAME_MSG;
|
||||
}
|
||||
break;
|
||||
case BOX:
|
||||
cod = BOX_MSG;
|
||||
break;
|
||||
case CYL:
|
||||
cod = CYLINDER_MSG;
|
||||
break;
|
||||
case SPHERE:
|
||||
cod = SPHERE_MSG;
|
||||
break;
|
||||
case CONE:
|
||||
cod = CONE_MSG;
|
||||
break;
|
||||
case TOR:
|
||||
cod = TORUS_MSG;
|
||||
break;
|
||||
case PRISM:
|
||||
cod = PRISM_MSG;
|
||||
break;
|
||||
case PYRAMID:
|
||||
cod = PYRAMID_MSG;
|
||||
break;
|
||||
case ELIPSOID:
|
||||
cod = MSG_SHU_016;
|
||||
break;
|
||||
case SPHERIC_BAND:
|
||||
cod = MSG_SHU_017;
|
||||
break;
|
||||
default:
|
||||
cod = UNKNOWN_OBJ_MSG;
|
||||
break;
|
||||
}
|
||||
strncpy(str, get_message(cod)->str, len - 1);
|
||||
str[len - 1] = 0;
|
||||
}
|
||||
|
||||
void ot_insert_str(hOBJ hobj, char *str, int len)
|
||||
{
|
||||
int bnum;
|
||||
lpIBLOCK blk;
|
||||
lpGEO_INSERT geo;
|
||||
lpOBJ obj;
|
||||
|
||||
|
||||
obj = (lpOBJ)hobj;
|
||||
geo = (lpGEO_INSERT)(obj->geo_data);
|
||||
bnum = geo->num;
|
||||
GetObjTypeCaption(obj->type, str, len);
|
||||
|
||||
if((blk = (IBLOCK *)get_elem(&vd_blocks, bnum)) != NULL){
|
||||
strncat(str, "\"", len - strlen(str) - 1);
|
||||
str[len - 1] = 0;
|
||||
strncat(str, blk->name, len - strlen(str) - 1);
|
||||
strncat(str, "\"", len - strlen(str) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ot_path_str(hOBJ hobj, char *str, int len)
|
||||
{
|
||||
lpOBJ obj;
|
||||
CODE_MSG code;
|
||||
void* par = NULL;
|
||||
|
||||
switch (get_primitive_param_2d(hobj, &par)) {
|
||||
case RECTANGLE:
|
||||
strncpy(str, get_message(MSG_SHU_038)->str, len - 1);
|
||||
str[len - 1] = 0;
|
||||
break;
|
||||
case POLYGON:
|
||||
strncpy(str, get_message(MSG_SHU_039)->str, len - 1);
|
||||
str[len - 1] = 0;
|
||||
break;
|
||||
default:
|
||||
obj = (lpOBJ)hobj;
|
||||
GetObjTypeCaption(obj->type, str, len);
|
||||
if (obj->status & ST_FLAT) code = MSG_PATH_FLATE;
|
||||
else code = MSG_PATH_NO_FLATE;
|
||||
strncat(str, get_message(code)->str, len - strlen(str) - 1);
|
||||
str[len - 1] = 0;
|
||||
if (obj->status & ST_CLOSE) code = MSG_PATH_CLOSE;
|
||||
else code = MSG_PATH_NO_CLOSE;
|
||||
strncat(str, get_message(code)->str, len - strlen(str) - 1);
|
||||
if (obj->status & ST_SIMPLE) code = MSG_PATH_NO_CROSS;
|
||||
else code = MSG_PATH_CROSS;
|
||||
strncat(str, get_message(code)->str, len - strlen(str) - 1);
|
||||
}
|
||||
if (par) SGFree(par); par = NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "../sg.h"
|
||||
|
||||
//---
|
||||
void off_blink_selected(void)
|
||||
{
|
||||
hOBJ hobj;
|
||||
|
||||
hobj = selected.hhead;
|
||||
while (hobj) {
|
||||
off_blink_one_obj(hobj);
|
||||
get_next_item_z(SEL_LIST,hobj,&hobj);
|
||||
}
|
||||
}
|
||||
void off_blink_one_obj(hOBJ hobj)
|
||||
{
|
||||
lpOBJ obj;
|
||||
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->status &= (~(ST_SELECT|ST_BLINK)); //
|
||||
// change_viobj_color(hobj,COBJ);
|
||||
//draw_obj(hobj,CDEFAULT);
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
#include "../sg.h"
|
||||
|
||||
/*
|
||||
|
||||
: scs - (short sx, short sy)
|
||||
vcs - (D_POINT vp)
|
||||
gcs - (D_POINT gp)
|
||||
ucs - (D_POINT up)
|
||||
cpl - (D_POINT cp)
|
||||
*/
|
||||
|
||||
//---
|
||||
lpD_POINT scs_to_vcs (short sx, short sy, lpD_POINT vp)
|
||||
{
|
||||
/* f_tfm(&curr_w3->fwind, sx, sy, &vp->x, &vp->y);
|
||||
vp->z = (curr_w3->type == CAM_VIEW) ? 0. : curr_point_vcs.z;*/
|
||||
return vp;
|
||||
}
|
||||
|
||||
//---
|
||||
void vcs_to_scs (lpD_POINT vp, short *sx, short *sy)
|
||||
{
|
||||
//f_tmf(&curr_w3->fwind, vp->x, vp->y, sx, sy);
|
||||
}
|
||||
|
||||
//---
|
||||
lpD_POINT vcs_to_gcs (lpD_POINT vp, lpD_POINT gp)
|
||||
{
|
||||
//MATR view_port_matr = {-1.0, 0.0, 0.0, 0.0,
|
||||
// 0.0, -1.0, 0.0, 0.0,
|
||||
// 0.0, 0.0, 1.0, 0.0,
|
||||
// 0.0, 0.0, 0.0, 1.0};
|
||||
//o_hcncrd(/*curr_w3->matri*/view_port_matr, vp, gp);
|
||||
assert(0);
|
||||
return gp;
|
||||
}
|
||||
|
||||
//---
|
||||
lpD_POINT gcs_to_vcs (lpD_POINT gp, lpD_POINT vp)
|
||||
{
|
||||
//MATR view_port_matr = {-1.0, 0.0, 0.0, 0.0,
|
||||
// 1.0, -1.0, 0.0, 0.0,
|
||||
// 0.0, 0.0, 1.0, 0.0,
|
||||
// 0.0, 0.0, 1.0, 1.0};
|
||||
//o_hcncrd(/*curr_w3->matrp*/view_port_matr, gp, vp);
|
||||
assert(0);
|
||||
return vp;
|
||||
}
|
||||
|
||||
//---
|
||||
lpD_POINT gcs_to_ucs (lpD_POINT gp, lpD_POINT up)
|
||||
{
|
||||
o_hcncrd(m_gcs_ucs, gp, up);
|
||||
return up;
|
||||
}
|
||||
|
||||
//---
|
||||
lpD_POINT ucs_to_gcs (lpD_POINT up, lpD_POINT gp)
|
||||
{
|
||||
o_hcncrd(m_ucs_gcs, up, gp);
|
||||
return gp;
|
||||
}
|
||||
|
||||
//---
|
||||
lpD_POINT scs_to_gcs (short sx, short sy, lpD_POINT gp)
|
||||
{
|
||||
return vcs_to_gcs(scs_to_vcs(sx,sy,gp),gp);
|
||||
}
|
||||
|
||||
//---
|
||||
void gcs_to_scs (lpD_POINT gp, short *sx, short *sy)
|
||||
{
|
||||
D_POINT vp;
|
||||
|
||||
vcs_to_scs(gcs_to_vcs(gp,&vp),sx,sy);
|
||||
}
|
||||
|
||||
//---
|
||||
lpD_POINT scs_to_ucs (short sx, short sy, lpD_POINT up)
|
||||
{
|
||||
return vcs_to_ucs(scs_to_vcs(sx,sy,up),up);
|
||||
}
|
||||
|
||||
//---
|
||||
void ucs_to_scs (lpD_POINT up, short *sx, short *sy)
|
||||
{
|
||||
D_POINT vp;
|
||||
|
||||
vcs_to_scs(ucs_to_vcs(up,&vp),sx,sy);
|
||||
}
|
||||
|
||||
//---
|
||||
lpD_POINT vcs_to_ucs (lpD_POINT vp, lpD_POINT up)
|
||||
{
|
||||
return gcs_to_ucs(vcs_to_gcs(vp,up),up);
|
||||
}
|
||||
|
||||
//---
|
||||
lpD_POINT ucs_to_vcs (lpD_POINT up, lpD_POINT vp)
|
||||
{
|
||||
return gcs_to_vcs(ucs_to_gcs(up,vp),vp);
|
||||
}
|
||||
|
||||
//---
|
||||
void gcs_to_vp (short vp, lpD_POINT gp, short *sx, short *sy)
|
||||
{
|
||||
//D_POINT p;
|
||||
|
||||
//o_hcncrd(vport[vp].wind3d.matrp, gp, &p);
|
||||
//f_tmf(&vport[vp].wind3d.fwind, p.x, p.y, sx, sy);
|
||||
}
|
||||
|
||||
//---
|
||||
static D_POINT cpl_abc; //
|
||||
extern BOOL super_flag;
|
||||
extern D_POINT super_normal, super_origin;
|
||||
#pragma argsused
|
||||
void cpl_init(TYPE_CS type)
|
||||
{
|
||||
D_POINT pp0, pp1;
|
||||
|
||||
if (super_flag) {
|
||||
gcs_to_vcs(&super_origin, &pp0);
|
||||
dpoint_add(&super_origin, &super_normal, &pp1);
|
||||
} else {
|
||||
DA_POINT p1 = {0,0,0};
|
||||
D_POINT p0 = {0,0,0};
|
||||
int axis = get_index_invalid_axis();
|
||||
|
||||
p1[axis] = 1;
|
||||
gcs_to_vcs(&pp0, &pp0);
|
||||
}
|
||||
gcs_to_vcs(&pp1, &pp1);
|
||||
dpoint_sub(&pp1, &pp0, &cpl_abc);
|
||||
}
|
||||
|
||||
//--- cpl_init() !
|
||||
lpD_POINT vcs_to_cpl(lpD_POINT vp, lpD_POINT cp)
|
||||
{
|
||||
sgFloat d;
|
||||
|
||||
d = dskalar_product(&cpl_abc, &curr_point_vcs);
|
||||
cp->x = vp->x;
|
||||
cp->y = vp->y;
|
||||
cp->z = - (cpl_abc.x * vp->x + cpl_abc.y * vp->y - d) / cpl_abc.z;
|
||||
return vcs_to_gcs(cp,cp);
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
#include "../sg.h"
|
||||
|
||||
/*
|
||||
(hobj2 == NULL)
|
||||
|
||||
|
||||
: OSTRUE -
|
||||
OSBREAK -
|
||||
OSFALSE - -
|
||||
*/
|
||||
|
||||
static sgFloat exec_alpha(lpD_POINT p, lpD_POINT p1, lpD_POINT p2);
|
||||
static short intersect_ll_on_line(lpGEO_LINE l1, lpGEO_LINE l2);
|
||||
|
||||
OSCAN_COD test_self_cross_path(hOBJ hobj, hOBJ hobj2)
|
||||
{
|
||||
MNODE node;
|
||||
lpMNODE lpnode;
|
||||
short i, j, kp;
|
||||
short count, count1 = 0, step;
|
||||
BOOL closed;
|
||||
OSTATUS status;
|
||||
GEO_LINE line1, line2;
|
||||
D_POINT mn1, mx1, mn2, mx2;
|
||||
VDIM vdim, vdim2;
|
||||
|
||||
if (!hobj2) { //
|
||||
if (!get_status_path(hobj, &status)) return OSFALSE;
|
||||
closed = (status & ST_CLOSE) ? TRUE : FALSE;
|
||||
if (!apr_path(&vdim, hobj)) return OSFALSE;
|
||||
count = ((int)(vdim.num_elem - 1) * (vdim.num_elem - 2)) / 2;
|
||||
if (count < 100) step = 1;
|
||||
else step = count / 100;
|
||||
// num_proc = start_grad(GetIDS(IDS_SG047), count);
|
||||
if (!read_elem(&vdim, 0, &node)) {
|
||||
err:
|
||||
// end_grad(num_proc , count);
|
||||
free_vdim(&vdim);
|
||||
return OSFALSE;
|
||||
err1:
|
||||
end_rw(&vdim);
|
||||
goto err;
|
||||
}
|
||||
line1.v1 = node.p;
|
||||
for (i = 1; i < vdim.num_elem - 1; i++) {
|
||||
if (ctrl_c_press) {
|
||||
put_message(CTRL_C_PRESS, NULL, 0);
|
||||
goto err;
|
||||
}
|
||||
if (!begin_rw(&vdim, i)) goto err;
|
||||
if ( (lpnode = (lpMNODE)get_next_elem(&vdim)) == NULL ) goto err1;
|
||||
line2.v1 = line1.v2 = lpnode->p;
|
||||
dpoint_minmax(&line1.v1, 2, &mn1, &mx1);
|
||||
for (j = i + 1; j < vdim.num_elem; j++) {
|
||||
count1++;
|
||||
// if (!(count1 % step)) step_grad(num_proc , count1);
|
||||
if ( (lpnode = (lpMNODE)get_next_elem(&vdim)) == NULL ) goto err1;
|
||||
line2.v2 = lpnode->p;
|
||||
dpoint_minmax(&line2.v1, 2, &mn2, &mx2);
|
||||
el_geo_err = EL_OK;
|
||||
if (inter_limits_two_obj(&mn1, &mx1, &mn2, &mx2)) {
|
||||
if (!intersect_3d_ll(&line1, TRUE, &line2, TRUE, &node.p, &kp)) {
|
||||
put_message(EMPTY_MSG,GetIDS(IDS_SG048),0);
|
||||
goto err1;
|
||||
}
|
||||
if (el_geo_err == EL_EQ_LINE) { //
|
||||
kp = intersect_ll_on_line(&line1, &line2);
|
||||
if (kp == -1) goto brk;
|
||||
}
|
||||
/*if (kp) {
|
||||
if (!(j == i + 1 ||
|
||||
(closed && j == vdim.num_elem - 1))) goto brk;
|
||||
}*/
|
||||
if (kp) {
|
||||
if ((j != i + 1)&&
|
||||
!(closed && j == vdim.num_elem - 1 && i==1))
|
||||
goto brk;
|
||||
}
|
||||
}
|
||||
line2.v1 = line2.v2;
|
||||
}
|
||||
end_rw(&vdim);
|
||||
line1.v1 = line1.v2;
|
||||
}
|
||||
// end_grad(num_proc , count);
|
||||
free_vdim(&vdim);
|
||||
return OSTRUE;
|
||||
brk:
|
||||
end_rw(&vdim);
|
||||
// end_grad(num_proc , count);
|
||||
free_vdim(&vdim);
|
||||
return OSBREAK;
|
||||
} else { //
|
||||
if (!apr_path(&vdim, hobj)) return OSFALSE;
|
||||
if (!apr_path(&vdim2, hobj2)) {
|
||||
free_vdim(&vdim);
|
||||
return OSFALSE;
|
||||
}
|
||||
count = (int)(vdim.num_elem - 1) * (vdim2.num_elem - 1);
|
||||
if (count < 100) step = 1;
|
||||
else step = count / 100;
|
||||
// num_proc = start_grad(GetIDS(IDS_SG047), count);
|
||||
if (!begin_rw(&vdim, 0)) goto err2;
|
||||
if ( (lpnode = (lpMNODE)get_next_elem(&vdim)) == NULL ) goto err3;
|
||||
line1.v1 = lpnode->p;
|
||||
for (i = 1; i < vdim.num_elem; i++) {
|
||||
if ( (lpnode = (lpMNODE)get_next_elem(&vdim)) == NULL ) goto err3;
|
||||
line1.v2 = lpnode->p;
|
||||
dpoint_minmax(&line1.v1, 2, &mn1, &mx1);
|
||||
if (!begin_rw(&vdim2, 0)) goto err3;
|
||||
if ( (lpnode = (lpMNODE)get_next_elem(&vdim2)) == NULL ) goto err4;
|
||||
line2.v1 = lpnode->p;
|
||||
for (j = 1; j < vdim2.num_elem; j++) {
|
||||
count1++;
|
||||
// if (!(count1 % step)) step_grad(num_proc , count1);
|
||||
if ( (lpnode = (lpMNODE)get_next_elem(&vdim2)) == NULL ) goto err4;
|
||||
line2.v2 = lpnode->p;
|
||||
dpoint_minmax(&line2.v1, 2, &mn2, &mx2);
|
||||
el_geo_err = EL_OK;
|
||||
if (inter_limits_two_obj(&mn1, &mx1, &mn2, &mx2)) {
|
||||
if (!intersect_3d_ll(&line1, TRUE, &line2, TRUE, &node.p, &kp)) {
|
||||
put_message(EMPTY_MSG,GetIDS(IDS_SG048),0);
|
||||
goto err4;
|
||||
}
|
||||
if (el_geo_err == EL_EQ_LINE) { //
|
||||
kp = intersect_ll_on_line(&line1, &line2);
|
||||
}
|
||||
if (kp) goto brk2;
|
||||
}
|
||||
line2.v1 = line2.v2;
|
||||
}
|
||||
end_rw(&vdim2);
|
||||
line1.v1 = line1.v2;
|
||||
}
|
||||
end_rw(&vdim);
|
||||
// end_grad(num_proc , count);
|
||||
free_vdim(&vdim);
|
||||
free_vdim(&vdim2);
|
||||
return OSTRUE;
|
||||
err2:
|
||||
// end_grad(num_proc , count);
|
||||
free_vdim(&vdim);
|
||||
free_vdim(&vdim2);
|
||||
return OSFALSE;
|
||||
err4:
|
||||
end_rw(&vdim2);
|
||||
err3:
|
||||
end_rw(&vdim);
|
||||
goto err2;
|
||||
brk2:
|
||||
end_rw(&vdim2);
|
||||
end_rw(&vdim);
|
||||
// end_grad(num_proc , count);
|
||||
free_vdim(&vdim);
|
||||
free_vdim(&vdim2);
|
||||
return OSBREAK;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// !
|
||||
BOOL inter_limits_two_obj(lpD_POINT mn1, lpD_POINT mx1,
|
||||
lpD_POINT mn2, lpD_POINT mx2)
|
||||
{
|
||||
if (mx2->x + eps_d < mn1->x || mn2->x - eps_d > mx1->x) return FALSE;
|
||||
if (mx2->y + eps_d < mn1->y || mn2->y - eps_d > mx1->y) return FALSE;
|
||||
if (mx2->z + eps_d < mn1->z || mn2->z - eps_d > mx1->z) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
p ,
|
||||
p1, p2
|
||||
*/
|
||||
static sgFloat exec_alpha(lpD_POINT p, lpD_POINT p1, lpD_POINT p2)
|
||||
{
|
||||
if (fabs(p2->x - p1->x) > eps_d) return (p->x - p1->x) / (p2->x - p1->x);
|
||||
if (fabs(p2->y - p1->y) > eps_d) return (p->y - p1->y) / (p2->y - p1->y);
|
||||
return (p->z - p1->z) / (p2->z - p1->z);
|
||||
}
|
||||
|
||||
/*
|
||||
,
|
||||
|
||||
: -1
|
||||
0
|
||||
1 ( )
|
||||
*/
|
||||
static short intersect_ll_on_line(lpGEO_LINE l1, lpGEO_LINE l2)
|
||||
{
|
||||
sgFloat al3, al4;
|
||||
|
||||
if (dpoint_eq(&l2->v1, &l1->v1, eps_d)) al3 = 0.;
|
||||
else if (dpoint_eq(&l2->v1, &l1->v2, eps_d)) al3 = 1.;
|
||||
else al3 = exec_alpha(&l2->v1, &l1->v1, &l1->v2);
|
||||
if (dpoint_eq(&l2->v2, &l1->v1, eps_d)) al4 = 0.;
|
||||
else if (dpoint_eq(&l2->v2, &l1->v2, eps_d)) al4 = 1.;
|
||||
else al4 = exec_alpha(&l2->v2, &l1->v1, &l1->v2);
|
||||
if ((al3 > 1. && al4 > 1.) ||
|
||||
(al3 < 0. && al4 < 0.)) return 0;
|
||||
if ((al3 < 0. && al4 == 0.) ||
|
||||
(al4 < 0. && al3 == 0.) ||
|
||||
(al3 > 1. && al4 == 1.) ||
|
||||
(al4 > 1. && al3 == 1.)) return 1;
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "../sg.h"
|
||||
//
|
||||
// maxlen - name 0
|
||||
void auto_name(const char * prefix, char * name, short maxlen)
|
||||
{
|
||||
short i,j,len;
|
||||
int num = 0;
|
||||
char number_txt[14];
|
||||
|
||||
len = strlen(prefix);
|
||||
i = 0;
|
||||
if ( len ) {
|
||||
for ( i=len-1; i >= 0; i--){
|
||||
if ( isdigit(prefix[i] ) ) continue;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
if ( i != len ) num = atol(&prefix[i] ); //
|
||||
}
|
||||
num++;
|
||||
//ltoa(num,number_txt,10);
|
||||
memcpy(name,prefix,i);
|
||||
len = strlen(number_txt);
|
||||
j = len;
|
||||
if ( len+i >= maxlen ) j = maxlen - i - 1;
|
||||
memcpy(&name[i],&number_txt[len-j],j);
|
||||
name[j + i ] =0;
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
#include "../sg.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* windows example = "C:\Documents and Settings\User\My Documents\Digi_ESP\blah.ggg"; */
|
||||
/* unix example ? = "/usr/bin/blah.ggg" */
|
||||
/* unix example2 ? = "/durp <-- just a drive name */
|
||||
|
||||
#define GetLastChar(x) strchr(x, '\0')
|
||||
#define NullTerminate(x) x[i] = '\0'
|
||||
|
||||
void splitpath(const char *path, char *drive, char *dir, char *fName, char *ext)
|
||||
{
|
||||
char separator = '\\';
|
||||
|
||||
char *endPoint = NULL,
|
||||
*pos = (char*) path,
|
||||
*temp = NULL,
|
||||
*lastChar = NULL;
|
||||
|
||||
unsigned int i = 0,
|
||||
unixStyle = 0;
|
||||
|
||||
/* initialize all the output strings in case we have to abort */
|
||||
if(drive) { strcpy(drive, ""); }
|
||||
if(dir) { strcpy(dir, ""); }
|
||||
if(fName) { strcpy(fName, ""); }
|
||||
if(ext) { strcpy(ext, ""); }
|
||||
|
||||
/* find the end of the string */
|
||||
lastChar = GetLastChar((char*)path);
|
||||
|
||||
if(path[0] == '/')
|
||||
{ separator = '/'; unixStyle = 1; }
|
||||
else
|
||||
separator = '\\';
|
||||
|
||||
/* first figure out whether it contains a drive name */
|
||||
endPoint = strchr((char*)path, separator);
|
||||
|
||||
/* unix style drives are of the form "/drivename/" */
|
||||
if(unixStyle)
|
||||
endPoint = strchr(endPoint + 1, separator);
|
||||
|
||||
/* we found a drive name */
|
||||
if(endPoint && (endPoint < lastChar))
|
||||
{
|
||||
if(drive)
|
||||
{
|
||||
for(i = 0; pos + i < endPoint; i++)
|
||||
drive[i] = pos[i];
|
||||
|
||||
NullTerminate(drive); /* null terminate the the drive string */
|
||||
}
|
||||
|
||||
pos = endPoint;
|
||||
}
|
||||
else if(unixStyle)
|
||||
{
|
||||
|
||||
if(drive)
|
||||
{
|
||||
for(i = 0; (pos + i) < lastChar; i++)
|
||||
drive[i] = pos[i];
|
||||
|
||||
NullTerminate(drive);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
/* this happens when theres no separators in the path name */
|
||||
endPoint = pos;
|
||||
|
||||
/* next, find the directory name, if any */
|
||||
temp = pos;
|
||||
|
||||
while(temp && (endPoint < lastChar) )
|
||||
{
|
||||
temp = strchr(endPoint + 1, separator);
|
||||
|
||||
if(temp) { endPoint = temp; }
|
||||
}
|
||||
|
||||
/* if true, it means there's an intermediate directory name */
|
||||
if( (endPoint) && (endPoint > pos) && (endPoint < lastChar))
|
||||
{
|
||||
if(dir)
|
||||
{
|
||||
for(i = 0; (pos + i) <= endPoint; i++)
|
||||
dir[i] = pos[i];
|
||||
|
||||
NullTerminate(dir);
|
||||
}
|
||||
|
||||
pos = ++endPoint;
|
||||
}
|
||||
else
|
||||
/* this happens when there's no separators in the path name */
|
||||
endPoint = pos;
|
||||
|
||||
/* find the file name */
|
||||
temp = pos;
|
||||
|
||||
while(temp && (endPoint < lastChar))
|
||||
{
|
||||
temp = strchr(endPoint + 1, '.');
|
||||
|
||||
if(temp) { endPoint = temp; }
|
||||
}
|
||||
|
||||
if( (endPoint > pos) && (endPoint < lastChar))
|
||||
{
|
||||
if(fName)
|
||||
{
|
||||
for(i = 0; pos + i < endPoint; i++)
|
||||
fName[i] = pos[i];
|
||||
|
||||
NullTerminate(fName);
|
||||
}
|
||||
|
||||
pos = endPoint;
|
||||
}
|
||||
else if(endPoint == pos)
|
||||
{
|
||||
/* in this case there is no extension */
|
||||
if(fName)
|
||||
{
|
||||
for(i = 0; (pos + i) < lastChar; i++)
|
||||
fName[i] = pos[i];
|
||||
|
||||
fName[i] = '\0';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* the remaining characters just get dumped as the extension */
|
||||
if(ext)
|
||||
{
|
||||
for(i = 0; pos + i < lastChar; i++)
|
||||
ext[i] = pos[i];
|
||||
|
||||
NullTerminate(ext);
|
||||
}
|
||||
|
||||
/* finished! :) */
|
||||
}
|
||||
|
||||
/* example of the kind of things you might have to deal with (though unlikely):
|
||||
drive = "C:\"
|
||||
dir = "\MyDocuments\"
|
||||
fName = "budget"
|
||||
ext = "doc" (not the need to add the dot)
|
||||
*/
|
||||
|
||||
void makepath(char *path, const char *drive, const char *dir, const char *fName, const char *ext)
|
||||
{
|
||||
char separator = '\\';
|
||||
char *lastChar = NULL;
|
||||
char *pos = NULL;
|
||||
|
||||
unsigned int i = 0,
|
||||
unixStyle = 0,
|
||||
sepCount = 0; /* number of consecutive separators */
|
||||
|
||||
|
||||
if(!path)
|
||||
return;
|
||||
|
||||
/* Initialize the path to nothing */
|
||||
strcpy(path, "");
|
||||
|
||||
if(drive)
|
||||
{
|
||||
if(drive[0] == '/')
|
||||
{
|
||||
unixStyle = 1; separator = '/';
|
||||
}
|
||||
|
||||
sepCount = 0;
|
||||
pos = (char*) drive;
|
||||
lastChar = GetLastChar((char*)drive);
|
||||
|
||||
if(lastChar == pos)
|
||||
goto directory;
|
||||
|
||||
for(; pos < lastChar; pos++)
|
||||
{
|
||||
sepCount = ( (*pos) == separator ) ? sepCount + 1 : 0;
|
||||
|
||||
/* filter out any extra separators */
|
||||
if(sepCount > 1) { continue; }
|
||||
|
||||
path[i++] = (*pos);
|
||||
}
|
||||
|
||||
if( (i) && path[i-1] != separator)
|
||||
path[i++] = separator;
|
||||
|
||||
NullTerminate(path);
|
||||
}
|
||||
|
||||
directory:
|
||||
|
||||
if(dir)
|
||||
{
|
||||
sepCount = 0;
|
||||
pos = (char*) dir;
|
||||
lastChar = GetLastChar((char*)dir);
|
||||
|
||||
if(pos == lastChar)
|
||||
goto fileName;
|
||||
|
||||
/* no character in the path yet? have to add that first separator */
|
||||
if(!i)
|
||||
path[i++] = separator; sepCount++;
|
||||
|
||||
/* getting rid of any extra separators */
|
||||
while( ((*pos) == separator) && (pos < lastChar) )
|
||||
pos++;
|
||||
|
||||
for( ; pos < lastChar; pos++)
|
||||
{
|
||||
sepCount = ( (*pos) == separator ) ? sepCount + 1 : 0;
|
||||
|
||||
if(sepCount > 1) { continue; }
|
||||
|
||||
path[i++] = (*pos);
|
||||
}
|
||||
|
||||
if( (i) && path[i-1] != separator)
|
||||
path[i++] = separator;
|
||||
|
||||
NullTerminate(path);
|
||||
}
|
||||
|
||||
fileName:
|
||||
|
||||
if(fName)
|
||||
{
|
||||
pos = (char*) fName;
|
||||
lastChar = GetLastChar((char*)fName);
|
||||
|
||||
if(lastChar == pos)
|
||||
goto extension;
|
||||
|
||||
for(sepCount = 0; pos < lastChar; pos++)
|
||||
{
|
||||
sepCount = ( (*pos) == '.' ) ? sepCount + 1 : 0;
|
||||
|
||||
if(sepCount > 1) { continue; }
|
||||
|
||||
path[i++] = (*pos);
|
||||
}
|
||||
|
||||
NullTerminate(path);
|
||||
}
|
||||
|
||||
extension:
|
||||
|
||||
if(ext)
|
||||
{
|
||||
sepCount = 0;
|
||||
pos = (char*) ext;
|
||||
lastChar = GetLastChar((char*)ext);
|
||||
|
||||
if(lastChar == pos)
|
||||
return;
|
||||
|
||||
if(i && (path[i - 1] != '.'))
|
||||
{ path[i++] = '.'; sepCount++; }
|
||||
|
||||
for(; pos < lastChar; pos++)
|
||||
{
|
||||
sepCount = ( (*pos) == '.' ) ? sepCount + 1 : 0;
|
||||
|
||||
if(sepCount > 1) { continue; }
|
||||
|
||||
path[i++] = (*pos);
|
||||
}
|
||||
|
||||
NullTerminate(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastChar = GetLastChar(path) - 1;
|
||||
|
||||
/* backpedal until we get rid of all the dots b/c what's the use of a dot on an extensionless file? */
|
||||
while(lastChar > path)
|
||||
{
|
||||
if((*lastChar) != '.')
|
||||
break;
|
||||
|
||||
(*lastChar) = '\0';
|
||||
lastChar--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef GetLastChar
|
||||
#undef NullTerminate
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--
|
||||
char* alltrim(char *str)
|
||||
{
|
||||
while (*str == ' ') strcpy(str, &str[1]);
|
||||
while (strlen(str) > 0 && str[strlen(str) - 1] == ' ')
|
||||
str[strlen(str) - 1] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
//--
|
||||
char* add_ext(char *name, char *def_ext)
|
||||
{
|
||||
char drive[MAXDRIVE];
|
||||
char dir[MAXDIR];
|
||||
char file[MAXFILE];
|
||||
char ext[MAXEXT];
|
||||
|
||||
fnsplit(name,drive,dir,file,ext);
|
||||
if (!ext[0]) fnmerge(name,drive,dir,file,def_ext);
|
||||
return name;
|
||||
}
|
||||
|
||||
//--
|
||||
char* chg_ext(char *name, char *def_ext)
|
||||
{
|
||||
char drive[MAXDRIVE];
|
||||
char dir[MAXDIR];
|
||||
char file[MAXFILE];
|
||||
char ext[MAXEXT];
|
||||
|
||||
fnsplit(name,drive,dir,file,ext);
|
||||
fnmerge(name,drive,dir,file,def_ext);
|
||||
return name;
|
||||
}
|
||||
|
||||
//---
|
||||
// , , ,
|
||||
// '\'
|
||||
// ':' ( ,
|
||||
// - .
|
||||
char* extract_path(char *path, const char *pathname)
|
||||
{
|
||||
char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
|
||||
char dummy = 0;
|
||||
|
||||
fnsplit(pathname, drive, dir, file, ext);
|
||||
fnmerge(path, drive, dir, &dummy, &dummy);
|
||||
return path;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
#include "../sg.h"
|
||||
|
||||
/*
|
||||
:
|
||||
- , ;
|
||||
-
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
hOBJ hobj_first, hobj_prev;
|
||||
UCHAR d_first, d_prev;
|
||||
GEO_OBJ prev_geo;
|
||||
OBJ prev_obj;
|
||||
D_POINT first_v, prev_v, first_vb;
|
||||
} CONTACT_DATA;
|
||||
typedef CONTACT_DATA * lpCONTACT_DATA;
|
||||
|
||||
static OSCAN_COD contact_geo_scan(hOBJ hobj,lpSCAN_CONTROL lpsc);
|
||||
static void set_contact_in_node(lpCONTACT_DATA data, hOBJ hobj,
|
||||
UCHAR direct, lpD_POINT curr_v);
|
||||
static OSTATUS get_mask_of_status(UCHAR direct);
|
||||
static lpD_POINT get_ptr_to_begin(OBJTYPE type, void * geo, UCHAR direct);
|
||||
|
||||
BOOL set_contacts_on_path(hOBJ hobj)
|
||||
{
|
||||
SCAN_CONTROL sc;
|
||||
CONTACT_DATA data = {NULL, NULL, 0, 0};
|
||||
lpOBJ obj;
|
||||
|
||||
init_scan(&sc);
|
||||
sc.user_geo_scan = contact_geo_scan;
|
||||
sc.data = &data;
|
||||
if (o_scan(hobj,&sc) == OSFALSE) return FALSE;
|
||||
//
|
||||
if (dpoint_eq(&data.first_vb,
|
||||
get_ptr_to_begin(data.prev_obj.type, &data.prev_geo, 1),
|
||||
eps_d)) {
|
||||
//
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->status |= ST_CLOSE;
|
||||
set_contact_in_node(&data, data.hobj_first, data.d_first, &data.first_v);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static OSCAN_COD contact_geo_scan(hOBJ hobj,lpSCAN_CONTROL lpsc)
|
||||
{
|
||||
lpCONTACT_DATA data = (lpCONTACT_DATA)lpsc->data;
|
||||
lpOBJ obj;
|
||||
UCHAR direct;
|
||||
GEO_OBJ curr_geo;
|
||||
OBJ curr_obj;
|
||||
D_POINT curr_v[2];
|
||||
|
||||
direct = (UCHAR)((lpsc->status & ST_DIRECT) ? 1 : 0);
|
||||
//
|
||||
get_simple_obj(hobj, &curr_obj, &curr_geo);
|
||||
if (direct) pereor_geo(curr_obj.type, &curr_geo);
|
||||
calc_geo_direction(curr_obj.type, &curr_geo, curr_v);
|
||||
if (!data->hobj_first) {
|
||||
//
|
||||
data->hobj_first = hobj;
|
||||
data->d_first = direct;
|
||||
data->first_v = curr_v[0];
|
||||
data->first_vb = *get_ptr_to_begin(curr_obj.type, &curr_geo, 0);
|
||||
//
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->status &= (UCHAR)(~get_mask_of_status((UCHAR)(!(data->d_first))));
|
||||
}
|
||||
if (data->hobj_prev)
|
||||
// A :
|
||||
set_contact_in_node(data, hobj, direct, curr_v);
|
||||
|
||||
//
|
||||
data->hobj_prev = hobj;
|
||||
data->d_prev = (UCHAR)(lpsc->status & ST_DIRECT);
|
||||
data->prev_obj = curr_obj;
|
||||
data->prev_geo = curr_geo;
|
||||
data->prev_v = curr_v[1];
|
||||
return OSTRUE;
|
||||
}
|
||||
|
||||
// A :
|
||||
static void set_contact_in_node(lpCONTACT_DATA data, hOBJ hobj,
|
||||
UCHAR direct, lpD_POINT curr_v)
|
||||
{
|
||||
lpOBJ obj;
|
||||
|
||||
switch (coll_tst(curr_v, TRUE, &data->prev_v, TRUE)) {
|
||||
case 1: //
|
||||
obj = (lpOBJ)data->hobj_prev;
|
||||
obj->status |= (UCHAR)(get_mask_of_status((UCHAR)(!(data->d_prev))));
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->status |= get_mask_of_status(direct);
|
||||
break;
|
||||
case 0: //
|
||||
case -1: // - 1
|
||||
obj = (lpOBJ)data->hobj_prev;
|
||||
obj->status &= (UCHAR)(~get_mask_of_status((UCHAR)(!(data->d_prev))));
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->status &= ~get_mask_of_status(direct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// .
|
||||
static OSTATUS get_mask_of_status(UCHAR direct)
|
||||
{
|
||||
OSTATUS status[2] = { ST_CONSTR1 , ST_CONSTR2 };
|
||||
|
||||
return status[direct];
|
||||
}
|
||||
|
||||
//
|
||||
void calc_geo_direction(OBJTYPE type, void * geo, lpD_POINT v)
|
||||
{
|
||||
D_POINT p[2];
|
||||
short i;
|
||||
|
||||
get_geo_endpoints_and_vectors(type, geo, p, v);
|
||||
for (i = 0; i < 2; i++)
|
||||
normv(TRUE, &v[i], &v[i]);
|
||||
|
||||
}
|
||||
|
||||
// /
|
||||
static lpD_POINT get_ptr_to_begin(OBJTYPE type, void * geo, UCHAR direct)
|
||||
{
|
||||
lpGEO_LINE line;
|
||||
lpGEO_ARC arc;
|
||||
lpD_POINT p;
|
||||
|
||||
switch (type) {
|
||||
case OLINE:
|
||||
line = (lpGEO_LINE)geo;
|
||||
p = (direct) ? &line->v2 : &line->v1;
|
||||
break;
|
||||
case OARC:
|
||||
arc = (lpGEO_ARC)geo;
|
||||
p = (direct) ? &arc->ve : &arc->vb;
|
||||
break;
|
||||
default:
|
||||
put_message(INTERNAL_ERROR,"S_CONTAC.C",0);
|
||||
p = (lpD_POINT)geo;
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
#include "../sg.h"
|
||||
|
||||
|
||||
bool is_path_on_one_line(hOBJ hobj)
|
||||
{
|
||||
lpOBJ pobj = (lpOBJ)hobj;
|
||||
|
||||
if (pobj->type!=OPATH)
|
||||
return false;
|
||||
|
||||
VDIM points_vdim;
|
||||
init_vdim(&points_vdim,sizeof(D_POINT));
|
||||
|
||||
VADR cur_adr = ((lpGEO_PATH)(pobj->geo_data))->listh.hhead;
|
||||
|
||||
while (cur_adr)
|
||||
{
|
||||
lpOBJ cur_obj = (lpOBJ)cur_adr;
|
||||
|
||||
if (cur_obj->type==OLINE)
|
||||
{
|
||||
lpGEO_LINE lineG = (lpGEO_LINE)cur_obj->geo_data;
|
||||
add_elem(&points_vdim, &lineG->v1);
|
||||
add_elem(&points_vdim, &lineG->v2);
|
||||
}
|
||||
else
|
||||
if (cur_obj->type==OARC)
|
||||
{
|
||||
free_vdim(&points_vdim);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
if (cur_obj->type==OPATH)
|
||||
{
|
||||
if (!is_path_on_one_line(cur_adr))
|
||||
{
|
||||
free_vdim(&points_vdim);
|
||||
return false;
|
||||
}
|
||||
D_POINT tmpP;
|
||||
get_endpoint_on_path(cur_adr,&tmpP,(OSTATUS)0);
|
||||
add_elem(&points_vdim, &tmpP);
|
||||
get_endpoint_on_path(cur_adr,&tmpP,ST_DIRECT);
|
||||
add_elem(&points_vdim, &tmpP);
|
||||
}
|
||||
|
||||
|
||||
get_next_item(cur_adr,&cur_adr);
|
||||
}
|
||||
|
||||
const int pntsCnt = points_vdim.num_elem;
|
||||
|
||||
if (pntsCnt<=2)
|
||||
{
|
||||
free_vdim(&points_vdim);
|
||||
return true;
|
||||
}
|
||||
|
||||
SG_POINT* p1 = (SG_POINT*)get_elem(&points_vdim,0);
|
||||
SG_POINT* p2 = (SG_POINT*)get_elem(&points_vdim,1);
|
||||
|
||||
for (int i=2;i<pntsCnt;i++)
|
||||
{
|
||||
SG_POINT* p3 = (SG_POINT*)get_elem(&points_vdim,i);
|
||||
if (!sgSpaceMath::IsPointsOnOneLine(*p1,*p2,*p3))
|
||||
{
|
||||
free_vdim(&points_vdim);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
free_vdim(&points_vdim);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
calc_plane == NULL
|
||||
: FALSE - - (.)
|
||||
TRUE - / ST_FLAT
|
||||
|
||||
|
||||
calc_plane != NULL
|
||||
: FALSE -
|
||||
(. )
|
||||
TRUE -
|
||||
*/
|
||||
BOOL set_flat_on_path(hOBJ hobj, lpD_PLANE calc_plane)
|
||||
{
|
||||
VDIM vdim;
|
||||
D_POINT root, first, second, a, b, /*d,*/ c = {0., 0., 0.};
|
||||
lpMNODE mnode;
|
||||
D_PLANE plane;
|
||||
BOOL ip, flat;
|
||||
lpOBJ obj;
|
||||
|
||||
// ""
|
||||
if (!apr_path(&vdim, hobj)) return FALSE;
|
||||
if (vdim.num_elem < 3) {
|
||||
if (calc_plane) return FALSE;
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->status |= ST_FLAT;
|
||||
return TRUE;
|
||||
}
|
||||
if (!begin_rw(&vdim, 0)) {
|
||||
err1:
|
||||
free_vdim(&vdim);
|
||||
return FALSE;
|
||||
}
|
||||
if ((mnode = (MNODE *)get_next_elem(&vdim)) == NULL) {
|
||||
err2:
|
||||
end_rw(&vdim);
|
||||
goto err1;
|
||||
}
|
||||
root = mnode->p;
|
||||
if ((mnode = (MNODE *)get_next_elem(&vdim)) == NULL) goto err2;
|
||||
first = mnode->p;
|
||||
/*while ((mnode = (MNODE *)get_next_elem(&vdim)) != NULL) {
|
||||
second = mnode->p;
|
||||
dpoint_sub(&first, &root, &a);
|
||||
dpoint_sub(&second, &root, &b);
|
||||
dvector_product(&a, &b, &d);
|
||||
c.x = c.x + fabs(d.x);
|
||||
c.y = c.y + fabs(d.y);
|
||||
c.z = c.z + fabs(d.z);
|
||||
first = second;
|
||||
}*/
|
||||
|
||||
/**RA*/while ((mnode = (MNODE *)get_next_elem(&vdim)) != NULL) {
|
||||
/**RA*/ second = mnode->p;
|
||||
/**RA*/ if (!sgSpaceMath::IsPointsOnOneLine(*((SG_POINT*)&root),
|
||||
/**RA*/ *((SG_POINT*)&first),
|
||||
/**RA*/ *((SG_POINT*)&second)) )
|
||||
/**RA*/ {
|
||||
/**RA*/ dpoint_sub(&first, &root, &a);
|
||||
/**RA*/ dpoint_sub(&second, &root, &b);
|
||||
/**RA*/ dvector_product(&a, &b, &c);
|
||||
/**RA*/ goto RALab;
|
||||
/**RA*/ }
|
||||
/**RA*/ else
|
||||
/**RA*/ continue;
|
||||
/**RA*/}
|
||||
// , ,
|
||||
// , - . .
|
||||
/**RA*/assert(0);
|
||||
/**RA*/goto err2;
|
||||
|
||||
|
||||
/**RA*/RALab:
|
||||
end_rw(&vdim);
|
||||
ip = dnormal_vector (&c);
|
||||
if (ip == FALSE) { //
|
||||
if (calc_plane) return FALSE;
|
||||
obj = (lpOBJ)hobj;
|
||||
obj->status |= ST_FLAT;
|
||||
return TRUE;
|
||||
}
|
||||
plane.v = c;
|
||||
plane.d = - dskalar_product(&root, &c);
|
||||
// ===
|
||||
flat = TRUE;
|
||||
if (!begin_rw(&vdim, 0)) goto err1;
|
||||
while ((mnode = (MNODE *)get_next_elem(&vdim)) != NULL) {
|
||||
|
||||
D_POINT ppp1 = plane.v;
|
||||
D_POINT ppp2 = mnode->p;
|
||||
|
||||
dnormal_vector(&ppp1);
|
||||
dnormal_vector(&ppp2);
|
||||
|
||||
sgFloat tV = dskalar_product(&ppp1, &ppp2);
|
||||
//sgFloat tV = dskalar_product(&plane.v, &mnode->p);
|
||||
sgFloat tmpVal = fabs(tV + plane.d);
|
||||
if (tmpVal >= eps_d) {
|
||||
flat = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
end_rw(&vdim);
|
||||
free_vdim(&vdim);
|
||||
if (calc_plane) {
|
||||
if (flat) {
|
||||
*calc_plane = plane;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
obj = (lpOBJ)hobj;
|
||||
if (flat) obj->status |= ST_FLAT;
|
||||
else obj->status &= ~ST_FLAT;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "../sg.h"
|
||||
|
||||
|
||||
FINDS serch_finds;
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "../sg.h"
|
||||
|
||||
// htest hout
|
||||
// O plane
|
||||
// , , !
|
||||
// : 1 - htest hout
|
||||
// -1 - htest hout
|
||||
// 0 -
|
||||
|
||||
short test_inside_path(hOBJ htest, hOBJ hout, lpD_PLANE plane)
|
||||
{
|
||||
int j, n, num;
|
||||
lpMNODE lpmnode;
|
||||
VDIM vdim;
|
||||
MATR m;
|
||||
D_POINT p, bp, ep;
|
||||
|
||||
if (!apr_path(&vdim, hout)) return 0;
|
||||
o_hcunit(m);
|
||||
o_hcrot1(m, &plane->v);
|
||||
get_endpoint_on_path(htest, &p, (OSTATUS)0);
|
||||
o_hcncrd(m, &p, &p);
|
||||
num = 0;
|
||||
if (!begin_rw(&vdim, 0)) goto err;
|
||||
for (j = 0; j < vdim.num_elem; j++) {
|
||||
if ( (lpmnode = (lpMNODE)get_next_elem(&vdim)) == NULL) goto err1;
|
||||
o_hcncrd(m, &lpmnode->p, &ep);
|
||||
if (j) {
|
||||
if((n = test_cont_int(&bp, &ep, &p)) < 0) {
|
||||
put_message(INTERNAL_ERROR, NULL, 0);
|
||||
goto err1;
|
||||
}
|
||||
num += n;
|
||||
}
|
||||
dpoint_copy(&bp, &ep);
|
||||
}
|
||||
end_rw(&vdim);
|
||||
free_vdim(&vdim);
|
||||
return (num % 2) ? 1 : -1; // htest / hout
|
||||
err1:
|
||||
end_rw(&vdim);
|
||||
err:
|
||||
free_vdim(&vdim);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "../sg.h"
|
||||
|
||||
// hpath plane
|
||||
// : 1 -
|
||||
// -1 -
|
||||
// 0 -
|
||||
// -2 -
|
||||
|
||||
short test_orient_path(hOBJ hpath, lpD_PLANE plane)
|
||||
{
|
||||
sgFloat s;
|
||||
MATR m;
|
||||
OSTATUS status;
|
||||
VDIM vdim;
|
||||
lpMNODE lpmnode;
|
||||
int j;
|
||||
D_POINT bp, ep;
|
||||
|
||||
if (!get_status_path(hpath, &status)) return -2;
|
||||
if (!(status & ST_CLOSE)) return 0;
|
||||
memset(&bp, 0, sizeof(bp));
|
||||
s = 0;
|
||||
o_hcunit(m);
|
||||
o_hcrot1(m, &plane->v);
|
||||
if (!apr_path(&vdim, hpath)) return -2;
|
||||
if (!begin_rw(&vdim, 0)) goto err;
|
||||
for (j = 0; j < vdim.num_elem; j++) {
|
||||
if ( (lpmnode = (lpMNODE)get_next_elem(&vdim)) == NULL) goto err1;
|
||||
o_hcncrd(m, &lpmnode->p, &ep);
|
||||
if (j) s += (bp.x * ep.y - ep.x * bp.y);
|
||||
dpoint_copy(&bp, &ep);
|
||||
}
|
||||
end_rw(&vdim);
|
||||
free_vdim(&vdim);
|
||||
return sg(s / 2, eps_n * eps_n);
|
||||
err1:
|
||||
end_rw(&vdim);
|
||||
err:
|
||||
free_vdim(&vdim);
|
||||
return -2;
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
#include "../sg.h"
|
||||
|
||||
static void zc_exit(void);
|
||||
|
||||
void zc_init(lpZCUT cut, sgFloat z)
|
||||
//
|
||||
{
|
||||
memset(cut, 0, sizeof(ZCUT));
|
||||
init_vdim(&cut->vdv, sizeof(ZCV));
|
||||
init_vdim(&cut->vdl, sizeof(ZCP));
|
||||
cut->z = z;
|
||||
}
|
||||
|
||||
void zc_free(lpZCUT cut)
|
||||
//
|
||||
{
|
||||
free_vdim(&cut->vdv);
|
||||
free_vdim(&cut->vdl);
|
||||
memset(cut, 0, sizeof(ZCUT));
|
||||
}
|
||||
|
||||
IDENT_V zcf_create_new_face(lpZCUT cut, UCHAR status)
|
||||
// cut
|
||||
// 0
|
||||
{
|
||||
ZCP f;
|
||||
IDENT_V id;
|
||||
|
||||
memset(&f, 0, sizeof(ZCP));
|
||||
f.status = status;
|
||||
if(!il_add_elem(&cut->vdl, &cut->freell, &cut->flisth, &f, 0, &id)){
|
||||
if(id < 0) return 0;
|
||||
else zc_exit();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
IDENT_V zcp_create_new_path(lpZCUT cut, IDENT_V idf, UCHAR status)
|
||||
// idf cut
|
||||
// hole = TRUE - -
|
||||
// 0
|
||||
{
|
||||
ZCP p;
|
||||
ZCP f;
|
||||
IDENT_V idp;
|
||||
|
||||
if(!read_elem(&cut->vdl, idf - 1, &f)) zc_exit();
|
||||
memset(&p, 0, sizeof(ZCP));
|
||||
p.idf = idf;
|
||||
p.status = status;
|
||||
if(!il_add_elem(&cut->vdl, &cut->freell, &f.listh, &p, 0, &idp)){
|
||||
if(idp < 0) return 0;
|
||||
else zc_exit();
|
||||
}
|
||||
if(!write_elem(&cut->vdl, idf - 1, &f)) zc_exit();
|
||||
return idp;
|
||||
}
|
||||
|
||||
IDENT_V zcv_add_to_tail(lpZCUT cut, IDENT_V idp, void* v, sgFloat k)
|
||||
// cut v idp
|
||||
// 0
|
||||
{
|
||||
ZCP p;
|
||||
ZCV vi;
|
||||
IDENT_V id, idv;
|
||||
|
||||
if(!read_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
id = (p.status & ZC_CLOSE) ? p.listh.tail : 0;
|
||||
memcpy(&vi.v, v, sizeof(D_PLPOINT));
|
||||
vi.k = k;
|
||||
if(!il_add_elem(&cut->vdv, &cut->freelv, &p.listh, &vi, id, &idv)){
|
||||
if(idv < 0) return 0;
|
||||
else zc_exit();
|
||||
}
|
||||
if(!write_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
return idv;
|
||||
}
|
||||
|
||||
void zcp_close(lpZCUT cut, IDENT_V idp)
|
||||
// cut idp
|
||||
{
|
||||
ZCP p;
|
||||
|
||||
if(!read_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
if(!il_close(&cut->vdv, &p.listh)) zc_exit();
|
||||
if(p.listh.num > 1) p.status |= ZC_CLOSE;
|
||||
if(!write_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
}
|
||||
|
||||
UCHAR zcp_status(lpZCUT cut, IDENT_V idp)
|
||||
// cut idp
|
||||
{
|
||||
ZCP p;
|
||||
|
||||
if(!read_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
return p.status;
|
||||
}
|
||||
|
||||
void zcp_set_status(lpZCUT cut, IDENT_V idp, UCHAR status)
|
||||
// cut idp
|
||||
{
|
||||
lpZCP p;
|
||||
|
||||
if( (p = (ZCP *)get_elem(&cut->vdl, idp - 1))== NULL ) zc_exit();
|
||||
p->status = status;
|
||||
}
|
||||
|
||||
IDENT_V zcf_get_first_face(lpZCUT cut)
|
||||
// cut
|
||||
// 0,
|
||||
{
|
||||
return cut->flisth.head;
|
||||
}
|
||||
|
||||
IDENT_V zcf_get_next_face(lpZCUT cut, IDENT_V idf)
|
||||
// cut , idf
|
||||
// 0, idf -
|
||||
{
|
||||
if(idf)
|
||||
if(!il_get_next_item(&cut->vdl, idf, &idf)) zc_exit();
|
||||
return idf;
|
||||
}
|
||||
|
||||
IDENT_V zcp_get_first_path_in_face(lpZCUT cut, IDENT_V idf)
|
||||
// idf cut
|
||||
//
|
||||
// 0,
|
||||
{
|
||||
lpZCP f;
|
||||
IDENT_V idp;
|
||||
|
||||
if( (f = (ZCP *)get_elem(&cut->vdl, idf - 1)) == NULL ) zc_exit();
|
||||
idp = f->listh.head;
|
||||
return idp;
|
||||
}
|
||||
|
||||
|
||||
IDENT_V zcp_get_next_path(lpZCUT cut, IDENT_V idp)
|
||||
// cut, idp
|
||||
// 0, idp -
|
||||
{
|
||||
if(idp)
|
||||
if(!il_get_next_item(&cut->vdl, idp, &idp)) zc_exit();
|
||||
return idp;
|
||||
}
|
||||
|
||||
|
||||
IDENT_V zcv_get_first_point(lpZCUT cut, IDENT_V idp, void* v, sgFloat* k)
|
||||
// v idp cut
|
||||
// 0,
|
||||
|
||||
{
|
||||
lpZCP p;
|
||||
IDENT_V id;
|
||||
|
||||
if( (p = (ZCP *)get_elem(&cut->vdl, idp - 1)) == NULL ) zc_exit();
|
||||
id = p->listh.head;
|
||||
if(id) zcv_get_point(cut, id, v, k);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
IDENT_V zcv_get_next_point(lpZCUT cut, IDENT_V idv, void* v, sgFloat* k)
|
||||
// v , idv cut
|
||||
// 0, idv -
|
||||
|
||||
{
|
||||
if(idv){
|
||||
if(!il_get_next_item(&cut->vdv, idv, &idv)) zc_exit();
|
||||
if(idv) zcv_get_point(cut, idv, v, k);
|
||||
}
|
||||
return idv;
|
||||
}
|
||||
|
||||
|
||||
IDENT_V zcv_get_prev_point(lpZCUT cut, IDENT_V idv, void* v, sgFloat* k)
|
||||
// v , idv cut
|
||||
// 0, idv -
|
||||
// - .
|
||||
// , , ,
|
||||
// ,
|
||||
// (. zcv_get_first_point)
|
||||
|
||||
{
|
||||
if(idv){
|
||||
if(!il_get_prev_item(&cut->vdv, idv, &idv)) zc_exit();
|
||||
if(idv) zcv_get_point(cut, idv, v, k);
|
||||
}
|
||||
return idv;
|
||||
}
|
||||
|
||||
|
||||
IDENT_V zcv_get_point(lpZCUT cut, IDENT_V idv, void* v, sgFloat* k)
|
||||
// idv cut
|
||||
// 0, idv -
|
||||
//
|
||||
|
||||
{
|
||||
lpZCV vi;
|
||||
|
||||
if(idv){
|
||||
if( (vi = (ZCV *)get_elem(&cut->vdv, idv - 1)) == NULL ) zc_exit();
|
||||
memcpy(v, &vi->v, sizeof(D_PLPOINT));
|
||||
*k = vi->k;
|
||||
idv = vi->list.next;
|
||||
}
|
||||
return idv;
|
||||
}
|
||||
void zcv_overwrite_point(lpZCUT cut, IDENT_V idv, void* v, sgFloat k)
|
||||
// idv cut
|
||||
{
|
||||
lpZCV vi;
|
||||
|
||||
if(idv){
|
||||
if( (vi = (ZCV *)get_elem(&cut->vdv, idv - 1)) == NULL ) zc_exit();
|
||||
memcpy(&vi->v, v, sizeof(D_PLPOINT));
|
||||
vi->k = k;
|
||||
}
|
||||
}
|
||||
|
||||
int zcp_get_num_point(lpZCUT cut, IDENT_V idp)
|
||||
// cut idp
|
||||
{
|
||||
ZCP p;
|
||||
if(!read_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
return p.listh.num;
|
||||
}
|
||||
|
||||
UCHAR zc_get_status(lpZCUT cut, IDENT_V idp)
|
||||
// idp
|
||||
{
|
||||
ZCP p;
|
||||
if(!read_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
return p.status;
|
||||
}
|
||||
|
||||
|
||||
void zcv_detach_point(lpZCUT cut, IDENT_V idp, IDENT_V idv)
|
||||
// cut idv idp
|
||||
{
|
||||
ZCP p;
|
||||
|
||||
if(!read_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
if(!il_detach_item(&cut->vdv, &p.listh, idv)) zc_exit();
|
||||
if(!il_attach_item_tail(&cut->vdv, &cut->freelv, idv)) zc_exit();
|
||||
if((p.status & ZC_CLOSE) && p.listh.num <= 1)
|
||||
p.status -= ZC_CLOSE;
|
||||
if(!write_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
}
|
||||
|
||||
IDENT_V zcv_insert_point(lpZCUT cut, IDENT_V idp, IDENT_V idv, void* v, sgFloat k)
|
||||
// cut v idp idv
|
||||
// idv = 0,
|
||||
// 0
|
||||
{
|
||||
ZCP p;
|
||||
ZCV vi;
|
||||
IDENT_V id;
|
||||
|
||||
if(!read_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
if(idv) id = idv;
|
||||
else id = (p.status & ZC_CLOSE) ? p.listh.tail : 0;
|
||||
memcpy(&vi.v, v, sizeof(D_PLPOINT));
|
||||
vi.k = k;
|
||||
if(!il_add_elem(&cut->vdv, &cut->freelv, &p.listh, &vi, id, &idv)){
|
||||
if(idv < 0) return 0;
|
||||
else zc_exit();
|
||||
}
|
||||
if(!write_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
return idv;
|
||||
}
|
||||
|
||||
void zcp_free_path(lpZCUT cut, IDENT_V idp)
|
||||
// idp cut
|
||||
{
|
||||
ZCP p;
|
||||
|
||||
if(!read_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
if(!il_attach_list_befo(&cut->vdv, &cut->freelv, 0, &p.listh)) zc_exit();
|
||||
il_init_listh(&p.listh);
|
||||
if(p.status & ZC_CLOSE) p.status -= ZC_CLOSE;
|
||||
if(!write_elem(&cut->vdl, idp - 1, &p)) zc_exit();
|
||||
}
|
||||
|
||||
void zcp_delete_path(lpZCUT cut, IDENT_V idf, IDENT_V idp)
|
||||
// idf cut idp
|
||||
{
|
||||
ZCP f;
|
||||
|
||||
zcp_free_path(cut, idp);
|
||||
if(!read_elem(&cut->vdl, idf - 1, &f)) zc_exit();
|
||||
if(!il_detach_item(&cut->vdl, &f.listh, idp)) zc_exit();
|
||||
if(!il_attach_item_tail(&cut->vdl, &cut->freell, idp)) zc_exit();
|
||||
if(!write_elem(&cut->vdl, idf - 1, &f)) zc_exit();
|
||||
}
|
||||
|
||||
static void zc_exit(void)
|
||||
{
|
||||
exit(1);
|
||||
// SG_save_and_exit(INTERNAL_ERROR, "ZCUTS");
|
||||
}
|
||||
@@ -0,0 +1,671 @@
|
||||
#include "../sg.h"
|
||||
|
||||
static IDENT_V zcp_equid(lpZCUT equid, IDENT_V idpw, IDENT_V idfeq,
|
||||
sgFloat h, BOOL app_arc);
|
||||
static IDENT_V zcp_equid_line(lpZCUT cut, lpZCUT equid, IDENT_V idface, IDENT_V idp,
|
||||
sgFloat h, sgFloat h2);
|
||||
static short get_point_param(lpD_POINT v0, lpD_POINT v1, lpD_POINT vnew);
|
||||
static BOOL define_k(lpZCUT cut, IDENT_V idp, sgFloat h1, sgFloat h2);
|
||||
static sgFloat len_vect(lpD_POINT p);
|
||||
static sgFloat get_max_h_1(lpZCUT cut, IDENT_V idl, sgFloat h);
|
||||
static sgFloat get_max_h_2(lpZCUT cut, IDENT_V idl, sgFloat h);
|
||||
static IDENT_V create_tmp_path(lpZCUT cut, lpZCUT equid, IDENT_V idface, IDENT_V idp);
|
||||
static IDENT_V create_tmp_path_null(lpZCUT cut, lpZCUT equid, IDENT_V idface, IDENT_V idp);
|
||||
|
||||
IDENT_V zcf_equid(lpZCUT cut, lpZCUT equid, IDENT_V idf, sgFloat h, sgFloat h2, BOOL app_arc)
|
||||
// ( h h2 )
|
||||
// idf cut
|
||||
// app_arc = TRUE, ( )
|
||||
// equid,
|
||||
// .
|
||||
//
|
||||
// h > 0, ,
|
||||
// ., - .
|
||||
// ,
|
||||
// 0
|
||||
{
|
||||
// short count = 0;
|
||||
int num_otr;
|
||||
UCHAR status;
|
||||
IDENT_V idfeq, idp, idp_cur, idpeq, idpw;
|
||||
lpZCUT cut_cur;
|
||||
sgFloat H, hmax_1, hmax_2, hcur;
|
||||
BOOL end, first;
|
||||
|
||||
status = zcp_status(cut, idf);
|
||||
idfeq = zcf_create_new_face(equid, status);
|
||||
if ( !idfeq ) return 0;
|
||||
idp = zcp_get_first_path_in_face(cut, idf);
|
||||
while ( idp ) { //
|
||||
if ( h == 0 ) {
|
||||
if ( (idpw = create_tmp_path_null(cut, equid, idfeq, idp)) < 0 ) return 0;
|
||||
idp = zcp_get_next_path(cut, idp);
|
||||
continue;
|
||||
}
|
||||
|
||||
num_otr = zcp_get_num_point(cut, idp);
|
||||
if ( num_otr == 2 ) { //
|
||||
/*idpw =*/ zcp_equid_line(cut, equid, idfeq, idp, h, h2);
|
||||
// if ( idpw > 0) count++; //
|
||||
idp = zcp_get_next_path(cut, idp);
|
||||
continue;
|
||||
}
|
||||
H = h; //
|
||||
cut_cur = cut;
|
||||
idp_cur = idp;
|
||||
first = TRUE;
|
||||
do {
|
||||
idpw = create_tmp_path(cut_cur, equid, idfeq, idp_cur);
|
||||
if ( idpw < 0) goto err;
|
||||
if ( idpw == 0) { //
|
||||
if ( cut_cur == equid ) { //
|
||||
zcp_delete_path(equid, idfeq, idp_cur); //
|
||||
}
|
||||
idp_cur = 0;
|
||||
break;
|
||||
}
|
||||
if ( first ) { //
|
||||
first = FALSE;
|
||||
if ( !define_k(equid, idpw, h, h2) ) goto err;
|
||||
}
|
||||
hmax_1 = get_max_h_1(equid, idpw, h); // ( > 0)
|
||||
hmax_2 = get_max_h_2(equid, idpw, h); // ( > 0)
|
||||
if ( hmax_1 == 0 || hmax_2 == 0 ) { //
|
||||
if ( cut_cur == equid ) { //
|
||||
zcp_delete_path(equid, idfeq, idp_cur); //
|
||||
idp_cur = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( fabs(hmax_1) < fabs(H) || fabs(hmax_2) < fabs(H) ) {
|
||||
hcur = min(hmax_1,hmax_2) * sg(h, eps_d);
|
||||
H = H - hcur;
|
||||
end = FALSE;
|
||||
} else {
|
||||
hcur = H;
|
||||
end = TRUE;
|
||||
}
|
||||
|
||||
idpeq = zcp_equid(equid, idpw, idfeq, hcur, app_arc);
|
||||
zcp_delete_path(equid, idfeq, idpw); //
|
||||
if ( cut_cur == equid ) { //
|
||||
zcp_delete_path(equid, idfeq, idp_cur); //
|
||||
}
|
||||
// if ( idpeq == 0 ) break; //
|
||||
cut_cur = equid;
|
||||
idp_cur = idpeq;
|
||||
} while ( !end && idpeq != 0);
|
||||
|
||||
if ( idp_cur ) { //
|
||||
idpw = create_tmp_path(equid, equid, idfeq, idp_cur);
|
||||
if ( idpw < 0) goto err;
|
||||
zcp_delete_path(equid, idfeq, idp_cur);
|
||||
// if ( idpw > 0) count++; //
|
||||
}
|
||||
idp = zcp_get_next_path(cut, idp);
|
||||
}
|
||||
|
||||
return idfeq;
|
||||
err:
|
||||
zcp_delete_path(equid, idfeq, idp_cur); //
|
||||
return 0;
|
||||
}
|
||||
static IDENT_V zcp_equid(lpZCUT equid, IDENT_V idpw, IDENT_V idfeq, sgFloat h, BOOL app_arc)
|
||||
// app_arc = TRUE, ( )
|
||||
// h idpw equid.
|
||||
// , .
|
||||
// , idfeq
|
||||
// ,
|
||||
// 0
|
||||
{
|
||||
IDENT_V idvbeg, idv0, idv1, idv2, idpeq;
|
||||
D_POINT v0, v1, v2, ve1, vb, c01, c12;
|
||||
D_POINT vp, vs1, vs2, vs3, vs4;
|
||||
BOOL flag = TRUE;
|
||||
int num_otr;
|
||||
short min_otr = 3, fl1, fl2; //, unclose = 1;
|
||||
sgFloat k0, k1, k2;
|
||||
UCHAR status, status1;
|
||||
|
||||
v0.z = v1.z = v2.z = ve1.z = vp.z = vb.z = 0.;
|
||||
vs1.z = vs2.z = vs3.z = vs4.z = 0.;
|
||||
status = status1 = zcp_status(equid, idpw);
|
||||
if ( status & ZC_CLOSE ) status1 -= ZC_CLOSE;
|
||||
if ( !(idpeq = zcp_create_new_path(equid, idfeq, status1)) ) return 0;
|
||||
|
||||
num_otr = zcp_get_num_point(equid, idpw); // - unclose;
|
||||
if ( num_otr < min_otr ) goto empty;
|
||||
|
||||
v0.z = v1.z = v2.z = 0;
|
||||
idv0 = zcv_get_first_point(equid, idpw, &v0, &k0);
|
||||
idv1 = zcv_get_next_point(equid, idv0, &v1, &k1);
|
||||
eq_line(&v0, &v1, &c01.x, &c01.y, &c01.z);
|
||||
vp = c01; vp.z = 0.;
|
||||
dpoint_scal(&vp, h*k0, &vp);
|
||||
dpoint_add(&v0, &vp, &vs1);
|
||||
if ( !(status & ZC_CLOSE) ) {
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &vs1, k0) ) goto empty;
|
||||
}
|
||||
idv2 = idvbeg = zcv_get_next_point(equid, idv1, &v2, &k2);
|
||||
|
||||
do {
|
||||
// eq_line(&v0, &v1, &c01.x, &c01.y, &c01.z);
|
||||
vp = c01; vp.z = 0.;
|
||||
dpoint_scal(&vp, h*k1, &vp);
|
||||
dpoint_add(&v0, &vp, &vs1);
|
||||
dpoint_add(&v1, &vp, &vs2);
|
||||
|
||||
eq_line(&v1, &v2, &c12.x, &c12.y, &c12.z);
|
||||
p_int_lines(c01.x, c01.y, c01.z - h*k1, c12.x, c12.y, c12.z - h*k1, &ve1);
|
||||
|
||||
//
|
||||
vp = c12; vp.z = 0.;
|
||||
dpoint_scal(&vp, h*k1, &vp);
|
||||
dpoint_add(&v1, &vp, &vs3);
|
||||
dpoint_add(&v2, &vp, &vs4);
|
||||
|
||||
fl1 = get_point_param(&vs1, &vs2, &ve1);
|
||||
fl2 = get_point_param(&vs3, &vs4, &ve1);
|
||||
if ( !app_arc ) { //
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &ve1, k1) ) goto empty;
|
||||
} else {
|
||||
if ( !flag ) { //
|
||||
// if ( fl1 >= 0 )
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &vs1, k1) ) goto empty;
|
||||
}
|
||||
if ( !(fl1 == 1 && fl2 == -1) ) { //
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &ve1, k1) ) goto empty;
|
||||
flag = TRUE;
|
||||
} else { //
|
||||
flag = FALSE;
|
||||
dpoint_sub(&ve1, &v1, &vp);
|
||||
dnormal_vector1(&vp); //
|
||||
dpoint_scal(&vp, fabs(h*k1), &vp);
|
||||
dpoint_add(&v1, &vp, &vb); //
|
||||
if ( dpoint_eq(&vb, &ve1, c_h_tolerance) ) { //
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &ve1, k1) ) goto empty;
|
||||
flag = TRUE;
|
||||
} else {
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &vs2, k1) ) goto empty;
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &vb, k1) ) goto empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*idv0 = idv1; */idv1 = idv2;
|
||||
v0 = v1; v1 = v2;
|
||||
c01 = c12;
|
||||
vs1 = vs3; vs2 = vs4; k1 = k2;
|
||||
idv2 = zcv_get_next_point(equid, idv1, &v2, &k2);
|
||||
v2.z = 0;
|
||||
} while ( idv2 != idvbeg && idv2 != 0 );
|
||||
|
||||
if ( !flag ) { //
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &vs1, k1) ) goto empty;
|
||||
}
|
||||
|
||||
vp = c01; vp.z = 0.;
|
||||
dpoint_scal(&vp, h*k1, &vp);
|
||||
dpoint_add(&v1, &vp, &vs2);
|
||||
|
||||
if ( status & ZC_CLOSE) zcp_close(equid, idpeq);
|
||||
else {
|
||||
if ( !zcv_add_to_tail(equid, idpeq, &vs2, k2) ) goto empty;
|
||||
}
|
||||
|
||||
//end:
|
||||
return idpeq;
|
||||
empty:
|
||||
if ( idpeq )
|
||||
zcp_free_path(equid, idpeq);
|
||||
return 0;
|
||||
}
|
||||
static sgFloat get_max_h_2(lpZCUT cut, IDENT_V idl, sgFloat h)
|
||||
//
|
||||
// ( )
|
||||
{
|
||||
IDENT_V idvbeg, idv0, idv1, idv2;
|
||||
D_POINT v0, v1, v2, v3;
|
||||
D_POINT w1, w2, w3, c, c1, c2, p, p1;
|
||||
D_POINT n = {0.,0.,1.}; //
|
||||
sgFloat hmin = MAXsgFloat, hcur, cs;
|
||||
sgFloat k0, k1, k2;
|
||||
|
||||
if ( h < 0 )dpoint_inv(&n, &n);
|
||||
|
||||
v0.z = v1.z = v2.z = v3.z = 0;
|
||||
idv0 = zcv_get_first_point(cut, idl, &v0, &k0);
|
||||
idv1= idvbeg = zcv_get_next_point(cut, idv0, &v1, &k1);
|
||||
idv2 = zcv_get_next_point(cut, idv1, &v2, &k2);
|
||||
dpoint_sub(&v0,&v1, &w1);
|
||||
dnormal_vector1(&w1); //
|
||||
if ( fabs(k0) < eps_d ) k0 = eps_d;
|
||||
if ( fabs(k1) < eps_d ) k1 = eps_d;
|
||||
if ( fabs(k2) < eps_d ) k2 = eps_d;
|
||||
|
||||
do {
|
||||
dpoint_sub(&v2,&v1, &w2);
|
||||
dnormal_vector1(&w2); //
|
||||
dpoint_add(&w1, &w2, &w3); //
|
||||
dvector_product(&w1, &w2, &c);
|
||||
dnormal_vector1(&c);
|
||||
n.z = 1;
|
||||
if ( h * k1 < 0 ) n.z = - n.z;
|
||||
cs = dskalar_product(&c, &n);
|
||||
if ( cs < 0 ) { //
|
||||
dpoint_add(&v1, &w3, &v3);
|
||||
eq_line(&v1, &v3, &c1.x, &c1.y, &c1.z); //
|
||||
|
||||
//
|
||||
dvector_product(&w1, &n, &c);
|
||||
dpoint_add(&v0, &c, &v3);
|
||||
eq_line(&v0, &v3, &c2.x, &c2.y, &c2.z);
|
||||
|
||||
if ( p_int_lines( c1.x, c1.y, c1.z, c2.x, c2.y, c2.z, &p) ) { //
|
||||
hcur = dist_p_l(&v0, &w1, &p, &p1) / k0; // k0 - v0
|
||||
if ( hcur < hmin ) hmin = hcur; // p
|
||||
}
|
||||
//
|
||||
dvector_product(&w2, &n, &c);
|
||||
dpoint_add(&v2, &c, &v3);
|
||||
eq_line(&v2, &v3, &c2.x, &c2.y, &c2.z);
|
||||
|
||||
if ( p_int_lines( c1.x, c1.y, c1.z, c2.x, c2.y, c2.z, &p) ) { //
|
||||
hcur = dist_p_l(&v2, &w2, &p, &p1) / k2; // k2 - v2
|
||||
if ( hcur < hmin ) hmin = hcur; // p
|
||||
}
|
||||
}
|
||||
|
||||
v0 = v1; v1 = v2; k0 = k1; k1 = k2;
|
||||
dpoint_inv(&w2, &w1);
|
||||
idv2 = zcv_get_next_point(cut, idv2, &v2, &k2);
|
||||
if ( fabs(k2) < eps_d ) k2 = eps_d;
|
||||
v2.z = 0;
|
||||
} while( idv2 != idvbeg && idv2 != 0);
|
||||
|
||||
return hmin;
|
||||
//met:
|
||||
// return 0;
|
||||
}
|
||||
|
||||
static sgFloat get_max_h_1(lpZCUT cut, IDENT_V idl, sgFloat h)
|
||||
//
|
||||
{
|
||||
IDENT_V idvbeg, idv0, idv1, idv2, idv3;
|
||||
D_POINT v0, v1, v2, v3;
|
||||
D_POINT w1, w2, w3, c, p, p1;
|
||||
D_POINT n = {0.,0.,1.}; //
|
||||
sgFloat hmin = MAXsgFloat, hcur, cs;
|
||||
sgFloat a1, b1, c1, a2, b2, c2;
|
||||
sgFloat k0, k1, k2;
|
||||
UCHAR status;
|
||||
|
||||
if ( h < 0 )dpoint_inv(&n, &n);
|
||||
|
||||
v0.z = v1.z = v2.z = v3.z = 0;
|
||||
idv0 = zcv_get_first_point(cut, idl, &v0, &k0);
|
||||
idv1 = zcv_get_next_point(cut, idv0, &v1, &k1);
|
||||
|
||||
status = zcp_status(cut, idl);
|
||||
if ( !(status & ZC_CLOSE) ) { //
|
||||
dpoint_sub(&v1,&v0, &w2);
|
||||
dnormal_vector1(&w2); //
|
||||
dvector_product(&n, &w2, &w3);
|
||||
v2 = v1; idv2 = idv1;
|
||||
v1 = v0; /*idv1 = idv0; */
|
||||
} else {
|
||||
idv2 = zcv_get_next_point(cut, idv1, &v2, &k2);
|
||||
dpoint_sub(&v0,&v1, &w1);
|
||||
dpoint_sub(&v2,&v1, &w2);
|
||||
dnormal_vector1(&w1); //
|
||||
dnormal_vector1(&w2); //
|
||||
dpoint_add(&w1, &w2, &w3); //
|
||||
dvector_product(&w1, &w2, &c);
|
||||
dnormal_vector1(&c); //
|
||||
cs = dskalar_product(&c, &n);
|
||||
/* if ( fabs(cs) <= eps_d ) { //
|
||||
dvector_product(&w1, &n, &w3);
|
||||
}
|
||||
*/
|
||||
if ( cs >= eps_d ) dpoint_inv(&w3, &w3); //
|
||||
}
|
||||
eq_line(&v1, dpoint_add(&v1, &w3, &c), &a1, &b1, &c1); //
|
||||
|
||||
idv3 = idvbeg = zcv_get_next_point(cut, idv2, &v3, &k2);
|
||||
// if ( idv3 == idv2 ) return 0;
|
||||
|
||||
do {
|
||||
dpoint_inv(&w2, &w1);
|
||||
dpoint_sub(&v3,&v2, &w2);
|
||||
dnormal_vector1(&w2); //
|
||||
dpoint_add(&w1, &w2, &w3); //
|
||||
|
||||
dvector_product(&w1, &w2, &c);
|
||||
dnormal_vector1(&c); //
|
||||
cs = dskalar_product(&c, &n);
|
||||
if (cs > 0.) dpoint_inv(&w3, &w3); //
|
||||
|
||||
eq_line(&v2, dpoint_add(&v2, &w3, &c), &a2, &b2, &c2); //
|
||||
|
||||
if ( p_int_lines( a1, b1, c1, a2, b2, c2, &p) ) { //
|
||||
dpoint_inv(&w1, &w1);
|
||||
hcur = dist_p_l(&v1, &w1, &p, &p1);
|
||||
if ( hcur < hmin ) { // p
|
||||
dpoint_sub(&p,&p1, &c);
|
||||
dnormal_vector1(&c); //
|
||||
dvector_product(&w1, &c, &p1);
|
||||
cs = dskalar_product(&p1, &n);
|
||||
if ( cs > 1 - eps_n ) //
|
||||
hmin = hcur;
|
||||
}
|
||||
}
|
||||
|
||||
a1 = a2; b1 = b2; c1 = c2; k1 = k2;
|
||||
v1 = v2; v2 = v3; idv2 = idv3;
|
||||
|
||||
idv3 = zcv_get_next_point(cut, idv2, &v3, &k2);
|
||||
v3.z = 0;
|
||||
} while( idv3 != idvbeg && idv3 != 0);
|
||||
|
||||
if ( idv3 == 0 ) { // ,
|
||||
dvector_product(&n, &w2, &w3);
|
||||
eq_line(&v2, dpoint_add(&v2, &w3, &c), &a2, &b2, &c2); //
|
||||
|
||||
if ( p_int_lines( a1, b1, c1, a2, b2, c2, &p) ) { //
|
||||
dpoint_inv(&w1, &w1);
|
||||
hcur = dist_p_l(&v1, &w1, &p, &p1);
|
||||
if ( hcur < hmin ) hmin = hcur;
|
||||
}
|
||||
}
|
||||
|
||||
return hmin;
|
||||
//met:
|
||||
// return 0;
|
||||
}
|
||||
static IDENT_V create_tmp_path(lpZCUT cut, lpZCUT equid, IDENT_V idface, IDENT_V idp)
|
||||
// idp cut,
|
||||
// equid, idface
|
||||
// : >0 -
|
||||
// 0 -
|
||||
// -1 -
|
||||
{
|
||||
short count;
|
||||
IDENT_V idvbeg, idv0, idv1, idv2, idv_b;
|
||||
D_POINT v0, v1, v2, c01; //, ve1, c12;
|
||||
int num_otr, num_count;
|
||||
short min_otr = 1, unclose = 1;
|
||||
IDENT_V idpw;
|
||||
UCHAR status;
|
||||
sgFloat k0, k1, k2;
|
||||
|
||||
status = zcp_status(cut, idp);
|
||||
count = 0;
|
||||
|
||||
if ( !(idpw = zcp_create_new_path(equid, idface, status))) return -1;
|
||||
// - idp
|
||||
v0.z = v1.z = v2.z = 0;
|
||||
idv0 = idvbeg = zcv_get_first_point(cut, idp, &v0, &k0);
|
||||
idv1 = zcv_get_next_point(cut, idv0, &v1, &k1);
|
||||
if ( status & ZC_CLOSE ) {
|
||||
/*idv2 = */ zcv_get_prev_point(cut, idv0, &v2, &k2);
|
||||
if ( !dpoint_eq(&v0, &v2, eps_d) ) {
|
||||
if ( eq_line(&v0, &v2, &c01.x, &c01.y, &c01.z) ) {
|
||||
if ( !zcv_add_to_tail(equid, idpw, &v0, k0) ) goto err;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( !zcv_add_to_tail(equid, idpw, &v0, k0) ) goto err;
|
||||
count++;
|
||||
|
||||
}
|
||||
while ( idv1 != idvbeg && idv1 != 0 ) { // ,
|
||||
if ( !dpoint_eq(&v0, &v1, eps_d) ) {
|
||||
if ( eq_line(&v0, &v1, &c01.x, &c01.y, &c01.z) ) {
|
||||
if ( !zcv_add_to_tail(equid, idpw, &v1, k1) ) goto err;
|
||||
count++;
|
||||
v0 = v1;
|
||||
}
|
||||
}
|
||||
idv1 = zcv_get_next_point(cut, idv1, &v1, &k1);
|
||||
v1.z = 0;
|
||||
}
|
||||
|
||||
if ( count < 3 ) goto empty;
|
||||
if ( status & ZC_CLOSE ) {
|
||||
zcp_close(equid, idpw);
|
||||
unclose = 0;
|
||||
min_otr = 3;
|
||||
}
|
||||
|
||||
num_otr = zcp_get_num_point(equid, idpw) - unclose;
|
||||
if ( num_otr < min_otr ) goto empty;
|
||||
|
||||
idv0 = idv_b = zcv_get_first_point(equid, idpw, &v0, &k0);
|
||||
idv1 = zcv_get_next_point(equid, idv0, &v1, &k1);
|
||||
idv2 = idvbeg = zcv_get_next_point(equid, idv1, &v2, &k2);
|
||||
eq_line(&v0, &v1, &c01.x, &c01.y, &c01.z);
|
||||
// eq_line(&v1, &v2, &c12.x, &c12.y, &c12.z);
|
||||
|
||||
count = 0;
|
||||
num_count = num_otr;
|
||||
while ( count <= num_count + 1 ) {
|
||||
count++;
|
||||
// if ( !dpoint_eq(&c01, &c12, eps_n) &&
|
||||
// !dpoint_eq(&c01, dpoint_inv(&c12, &ve1), eps_n) ) {
|
||||
if ( fabs(c01.x*v2.x + c01.y*v2.y + c01.z) > eps_d ) {
|
||||
v0 = v1; v1 = v2; //c01 = c12;
|
||||
idv0 = idv1; idv1 = idv2;
|
||||
} else { //
|
||||
zcv_detach_point(equid, idpw, idv1);
|
||||
num_otr--;
|
||||
if ( !dpoint_eq(&v0, &v2, eps_d) ) {
|
||||
if ( eq_line(&v0, &v2, &c01.x, &c01.y, &c01.z) ) {
|
||||
v1 = v2; // ,
|
||||
idv1 = idv2;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
if ( idv0 != idv_b || status & ZC_CLOSE ) { // v0
|
||||
idv1 = idv0; v1 = v0; k1 = k0; // v2 v0
|
||||
idv0 = zcv_get_prev_point(equid, idv1, &v0, &k0);
|
||||
zcv_detach_point(equid, idpw, idv2);
|
||||
idv2 = idv1;
|
||||
} else { // v0
|
||||
idv1 = zcv_get_next_point(equid, idv0, &v1, &k1);
|
||||
idv2 = idv1;
|
||||
}
|
||||
num_otr--;
|
||||
// if ( idv2 == idvbeg || idv2 == 0 ) break;
|
||||
// eq_line(&v0, &v1, &c01.x, &c01.y, &c01.z);
|
||||
}
|
||||
next:
|
||||
idv2 = zcv_get_next_point(equid, idv2, &v2, &k2);
|
||||
if ( idv2 == idvbeg || idv2 == 0 ) break;
|
||||
eq_line(&v0, &v1, &c01.x, &c01.y, &c01.z);
|
||||
// eq_line(&v1, &v2, &c12.x, &c12.y, &c12.z);
|
||||
}
|
||||
|
||||
if ( num_otr < min_otr ) goto empty;
|
||||
|
||||
return idpw;
|
||||
|
||||
err:
|
||||
zcp_delete_path(equid, idface, idpw); //
|
||||
return -1;
|
||||
empty:
|
||||
zcp_delete_path(equid, idface, idpw); //
|
||||
return 0;
|
||||
}
|
||||
static IDENT_V create_tmp_path_null(lpZCUT cut, lpZCUT equid, IDENT_V idface, IDENT_V idp)
|
||||
// 0 !!!!!
|
||||
// idp cut,
|
||||
// equid, idface
|
||||
// 0 -
|
||||
{
|
||||
// short count;
|
||||
IDENT_V idvbeg, idv0, idv1; //, idv2;
|
||||
D_POINT v0, v1, v2, c01; //, ve1, c12;
|
||||
// int num_otr;
|
||||
// short min_otr = 1, unclose = 1;
|
||||
IDENT_V idpw;
|
||||
UCHAR status;
|
||||
sgFloat k0, k1, k2;
|
||||
|
||||
status = zcp_status(cut, idp);
|
||||
// count = 0;
|
||||
|
||||
if ( !(idpw = zcp_create_new_path(equid, idface, status))) return 0;
|
||||
// - idp
|
||||
v0.z = v1.z = v2.z = 0;
|
||||
idv0 = idvbeg = zcv_get_first_point(cut, idp, &v0, &k0);
|
||||
idv1 = zcv_get_next_point(cut, idv0, &v1, &k1);
|
||||
if ( status & ZC_CLOSE ) {
|
||||
// idv2 = zcv_get_prev_point(cut, idv0, &v2);
|
||||
zcv_get_prev_point(cut, idv0, &v2, &k2);
|
||||
if ( !dpoint_eq(&v0, &v2, eps_d) ) {
|
||||
if ( eq_line(&v0, &v2, &c01.x, &c01.y, &c01.z) ) {
|
||||
if ( !zcv_add_to_tail(equid, idpw, &v0, k0) ) goto empty;
|
||||
// count++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( !zcv_add_to_tail(equid, idpw, &v0, k0) ) goto empty;
|
||||
// count++;
|
||||
|
||||
}
|
||||
while ( idv1 != idvbeg && idv1 != 0 ) { // ,
|
||||
if ( !dpoint_eq(&v0, &v1, eps_d) ) {
|
||||
if ( eq_line(&v0, &v1, &c01.x, &c01.y, &c01.z) ) {
|
||||
if ( !zcv_add_to_tail(equid, idpw, &v1, k1) ) goto empty;
|
||||
// count++;
|
||||
v0 = v1;
|
||||
}
|
||||
}
|
||||
idv1 = zcv_get_next_point(cut, idv1, &v1, &k1);
|
||||
v1.z = 0;
|
||||
}
|
||||
|
||||
if ( status & ZC_CLOSE ) zcp_close(equid, idpw);
|
||||
|
||||
return idpw;
|
||||
|
||||
empty:
|
||||
zcp_delete_path(equid, idface, idpw); //
|
||||
return 0;
|
||||
}
|
||||
static short get_point_param(lpD_POINT v0, lpD_POINT v1, lpD_POINT vnew)
|
||||
// : -1, vnew v0
|
||||
// 1, vnew v0
|
||||
// 0, vnew v0 v1, v0 v1
|
||||
{
|
||||
D_POINT vect1, vect2;
|
||||
sgFloat lv;
|
||||
|
||||
if ( dpoint_eq(v0, vnew, eps_d) ) return 0; // v0
|
||||
if ( dpoint_eq(v1, vnew, eps_d) ) return 0; // v1
|
||||
dpoint_sub(v1, v0, &vect1);
|
||||
dpoint_sub(vnew, v0, &vect2);
|
||||
lv = len_vect(&vect2); // vect2
|
||||
if(coll_tst(&vect1, FALSE, &vect2, FALSE) != 1) return -1;
|
||||
else if(lv > len_vect(&vect1) + eps_d) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static sgFloat len_vect(lpD_POINT p){
|
||||
return hypot(p->x, p->y);
|
||||
}
|
||||
// idp
|
||||
// h1 - , h2 -
|
||||
// -
|
||||
static BOOL define_k(lpZCUT cut, IDENT_V idp, sgFloat h1, sgFloat h2)
|
||||
{
|
||||
IDENT_V idvb, idv; //, idv1;
|
||||
D_POINT vn, vk; //, p;
|
||||
// IDENT_V idpw;
|
||||
// UCHAR status;
|
||||
sgFloat L, l, k;
|
||||
|
||||
// status = zcp_status(cut, idp);
|
||||
|
||||
//
|
||||
vn.z = vk.z = 0.;
|
||||
L = 0;
|
||||
idv = idvb = zcv_get_first_point(cut, idp, &vn, &k);
|
||||
do {
|
||||
idv = zcv_get_next_point(cut, idv, &vk, &k);
|
||||
if (idv == 0) break; //
|
||||
L += dpoint_distance(&vn, &vk);
|
||||
vn = vk;
|
||||
} while (idv != idvb);
|
||||
|
||||
// if ( !(idpw = zcp_create_new_path(cut, idface, status))) return 0;
|
||||
// - idp
|
||||
idv = idvb = zcv_get_first_point(cut, idp, &vn, &k);
|
||||
vn.z = vk.z = 0.;
|
||||
l = 0; //
|
||||
k = 1;
|
||||
zcv_overwrite_point(cut, idv, &vn, k);
|
||||
// if ( !zcv_add_to_tail(cut, idpw, &p) ) goto empty;
|
||||
do {
|
||||
idv = zcv_get_next_point(cut, idv, &vk, &k);
|
||||
if (idv == 0) break; //
|
||||
l += dpoint_distance(&vn, &vk);
|
||||
k = 1 - l/L*(1 - h2/h1);
|
||||
// if ( !zcv_add_to_tail(cut, idpw, &vk) ) goto empty;
|
||||
zcv_overwrite_point(cut, idv, &vk, k);
|
||||
// idv = idv1;
|
||||
vn = vk;
|
||||
} while (idv != idvb);
|
||||
|
||||
// if ( status & ZC_CLOSE ) zcp_close(cut, idpw);
|
||||
|
||||
return TRUE;
|
||||
|
||||
//empty:
|
||||
// zcp_delete_path(cut, idface, idpw); //
|
||||
// return FALSE;
|
||||
}
|
||||
static IDENT_V zcp_equid_line(lpZCUT cut, lpZCUT equid, IDENT_V idface, IDENT_V idp,
|
||||
sgFloat h, sgFloat h2)
|
||||
{
|
||||
short count;
|
||||
sgFloat k;
|
||||
IDENT_V idv0; //, idv1;
|
||||
D_POINT v0, v1, p1, p2, pn, pc;
|
||||
IDENT_V idpw;
|
||||
UCHAR status;
|
||||
|
||||
count = 0;
|
||||
|
||||
status = zcp_status(cut, idp);
|
||||
if ( !(idpw = zcp_create_new_path(equid, idface, status))) return -1;
|
||||
v0.z = v1.z = 0;
|
||||
idv0 = zcv_get_first_point(cut, idp, &v0, &k);
|
||||
zcv_get_next_point(cut, idv0, &v1, &k);
|
||||
|
||||
if ( dpoint_eq(&v0, &v1, eps_d) ) goto empty;
|
||||
|
||||
pn = v0;
|
||||
pn.z = 1;
|
||||
dpoint_sub(&v1, &v0, &p1);
|
||||
dpoint_sub(&pn, &v0, &p2);
|
||||
dvector_product(&p2, &p1, &pn);
|
||||
dnormal_vector(&pn); // ,
|
||||
|
||||
dpoint_scal(&pn, h, &pc);
|
||||
dpoint_add(&v0, &pc, &p1);
|
||||
dpoint_scal(&pn, h2, &pc);
|
||||
dpoint_add(&v1, &pc, &p2);
|
||||
|
||||
if ( !zcv_add_to_tail(equid, idpw, &p1, h) ) { count = -1; goto empty; }
|
||||
if ( !zcv_add_to_tail(equid, idpw, &p2, h2) ) { count = -1; goto empty; }
|
||||
|
||||
return idpw;
|
||||
|
||||
empty:
|
||||
zcp_delete_path(equid, idface, idpw); //
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
#include "../sg.h"
|
||||
/*
|
||||
, ..
|
||||
- , - .
|
||||
|
||||
( ) .
|
||||
, .
|
||||
|
||||
-
|
||||
,
|
||||
|
||||
:
|
||||
|
||||
hole - TRUE ""
|
||||
FALSE ""
|
||||
closed - TRUE
|
||||
FALSE
|
||||
:
|
||||
listh - SEL_LIST, - -
|
||||
fplane - TRUE,
|
||||
FALSE,
|
||||
.
|
||||
plane - ( fplane == TRUE!)
|
||||
|
||||
: G_OK - " "
|
||||
G_KEY -
|
||||
-
|
||||
|
||||
*/
|
||||
TEST_CORRECT_PATHS_RES test_correct_paths_array_for_face_command(hOBJ out_obj,
|
||||
hOBJ* int_objcs,
|
||||
int int_objcs_count)
|
||||
{
|
||||
lpOBJ obj;
|
||||
OSCAN_COD code;
|
||||
D_PLANE out_plane; //
|
||||
D_PLANE plane1; //
|
||||
int out_orient; //
|
||||
int orient; //
|
||||
|
||||
if (int_objcs_count==0)
|
||||
return TCPR_SUCCESS;
|
||||
|
||||
obj = (lpOBJ)out_obj;
|
||||
if (obj->type!=OCIRCLE && !(obj->status & ST_CLOSE))
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_NO_CLOSE;
|
||||
}
|
||||
if (obj->type!=OCIRCLE && !(obj->status & ST_FLAT))
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_NO_FLAT;
|
||||
}
|
||||
if (!set_flat_on_path(out_obj, &out_plane))
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_NO_FLAT;
|
||||
}
|
||||
out_orient = test_orient_path(out_obj, &out_plane);
|
||||
if (out_orient != 1 && out_orient != -1)
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_WITH_BAD_ORIENT;
|
||||
}
|
||||
|
||||
for (int i=0; i<int_objcs_count; i++)
|
||||
{
|
||||
obj = (lpOBJ)int_objcs[i];
|
||||
if (obj->type!=OCIRCLE && !(obj->status & ST_CLOSE))
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_NO_CLOSE;
|
||||
}
|
||||
if (obj->type!=OCIRCLE && !(obj->status & ST_FLAT))
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_NO_FLAT;
|
||||
}
|
||||
if (!set_flat_on_path(int_objcs[i], &plane1))
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_NO_FLAT;
|
||||
}
|
||||
if (!((dpoint_eq(&out_plane.v,&plane1.v,eps_n) &&
|
||||
fabs(out_plane.d - plane1.d) < eps_d) ||
|
||||
(dpoint_eq(&out_plane.v,dpoint_inv(&plane1.v,&plane1.v),eps_n) &&
|
||||
fabs(out_plane.d + plane1.d) < eps_d)))
|
||||
{
|
||||
//
|
||||
return TCPR_NOT_IN_ONE_PLANE;
|
||||
}
|
||||
code = test_self_cross_path(int_objcs[i], out_obj);
|
||||
if (code == OSBREAK)
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_INTERSECTS;
|
||||
}
|
||||
if (code != OSTRUE)
|
||||
{
|
||||
// -
|
||||
return TCPR_EXIST_INTERSECTS;
|
||||
}
|
||||
if (test_inside_path(int_objcs[i], out_obj, &out_plane) != 1)
|
||||
{
|
||||
//
|
||||
return TCPR_BAD_INCLUDES;
|
||||
}
|
||||
for (int j=i+1; j<int_objcs_count; j++)
|
||||
{
|
||||
code = test_self_cross_path(int_objcs[i], int_objcs[j]);
|
||||
if (code == OSBREAK)
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_INTERSECTS;
|
||||
}
|
||||
if (code != OSTRUE)
|
||||
{
|
||||
// -
|
||||
return TCPR_EXIST_INTERSECTS;
|
||||
}
|
||||
if (test_inside_path(int_objcs[i], int_objcs[j], &out_plane) != -1)
|
||||
{
|
||||
//
|
||||
return TCPR_BAD_INCLUDES;
|
||||
}
|
||||
if (test_inside_path(int_objcs[j], int_objcs[i], &out_plane) != -1)
|
||||
{
|
||||
//
|
||||
return TCPR_BAD_INCLUDES;
|
||||
}
|
||||
}
|
||||
orient = test_orient_path(int_objcs[i], &out_plane);
|
||||
if (orient != 1 && orient != -1)
|
||||
{
|
||||
//
|
||||
return TCPR_EXIST_WITH_BAD_ORIENT;
|
||||
}
|
||||
if (orient * out_orient > 0)
|
||||
{ //
|
||||
obj = (lpOBJ)int_objcs[i];
|
||||
obj->status ^= ST_DIRECT;
|
||||
}
|
||||
}
|
||||
return TCPR_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user