示例#1
0
文件: revolve.c 项目: kanzure/brlcad
/**
 * Returns -
 * -1 failure
 * 0 OK.  *r points to nmgregion that holds this tessellation.
 */
int
rt_revolve_tess(struct nmgregion **UNUSED(r), struct model *UNUSED(m), struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol))
{
    struct rt_revolve_internal *rip = NULL;
    struct rt_sketch_internal *sketch_ip = NULL;
    struct rt_curve *crv = NULL;

    RT_CK_DB_INTERNAL(ip);
    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    RT_REVOLVE_CK_MAGIC(rip);

    if (!rip->skt) {
	bu_log("rt_revolve_tess: ERROR: no sketch for revolve!\n");
	return -1;
    }

    sketch_ip = rip->skt;

    RT_SKETCH_CK_MAGIC(sketch_ip);

    crv = &sketch_ip->curve;

    if (crv->count < 1)
	return 0;

    /* FIXME: unimplemented */
    bu_log("Sorry, tessellation of revolve primitives is not yet implemented.\n");

    return -1;
}
示例#2
0
文件: sketch.c 项目: kanzure/brlcad
int
mk_sketch(struct rt_wdb *fp, const char *name, const struct rt_sketch_internal *skt)
{
    struct rt_sketch_internal *sketch;

    RT_SKETCH_CK_MAGIC(skt);

    /* copy the caller's struct */
    sketch = rt_copy_sketch(skt);

    return wdb_export(fp, name, (void *)sketch, ID_SKETCH, mk_conv2mm);
}
示例#3
0
/*
 * Default keypoint in model space is established in "pt". Returns
 * GED_ERROR if unable to determine a keypoint, otherwise returns
 * GED_OK.
 */
int
_ged_get_solid_keypoint(struct ged *const gedp,
			fastf_t *const pt,
			const struct rt_db_internal *const ip,
			const fastf_t *const mat)
{
    point_t mpt;

    RT_CK_DB_INTERNAL(ip);

    switch (ip->idb_type) {
	case ID_CLINE:
	    {
		struct rt_cline_internal *cli =
		    (struct rt_cline_internal *)ip->idb_ptr;

		RT_CLINE_CK_MAGIC(cli);

		VMOVE(mpt, cli->v);
		break;
	    }
	case ID_PARTICLE:
	    {
		struct rt_part_internal *part =
		    (struct rt_part_internal *)ip->idb_ptr;

		RT_PART_CK_MAGIC(part);

		VMOVE(mpt, part->part_V);
		break;
	    }
	case ID_PIPE:
	    {
		struct rt_pipe_internal *pipeip;
		struct wdb_pipept *pipe_seg;

		pipeip = (struct rt_pipe_internal *)ip->idb_ptr;

		RT_PIPE_CK_MAGIC(pipeip);

		pipe_seg = BU_LIST_FIRST(wdb_pipept, &pipeip->pipe_segs_head);
		VMOVE(mpt, pipe_seg->pp_coord);
		break;
	    }
	case ID_METABALL:
	    {
		struct rt_metaball_internal *metaball =
		    (struct rt_metaball_internal *)ip->idb_ptr;
		struct wdb_metaballpt *metaballpt;

		RT_METABALL_CK_MAGIC(metaball);

		VSETALL(mpt, 0.0);
		metaballpt = BU_LIST_FIRST(wdb_metaballpt,
					   &metaball->metaball_ctrl_head);
		VMOVE(mpt, metaballpt->coord);
		break;
	    }
	case ID_ARBN:
	    {
		struct rt_arbn_internal *arbn =
		    (struct rt_arbn_internal *)ip->idb_ptr;
		size_t i, j, k;
		int good_vert = 0;

		RT_ARBN_CK_MAGIC(arbn);
		for (i = 0; i < arbn->neqn; i++) {
		    for (j = i + 1; j < arbn->neqn; j++) {
			for (k = j + 1; k < arbn->neqn; k++) {
			    if (!bn_mkpoint_3planes(mpt, arbn->eqn[i],
						    arbn->eqn[j],
						    arbn->eqn[k])) {
				size_t l;

				good_vert = 1;
				for (l = 0; l < arbn->neqn; l++) {
				    if (l == i || l == j || l == k)
					continue;

				    if (DIST_PT_PLANE(mpt,
					arbn->eqn[l]) >
					gedp->ged_wdbp->wdb_tol.dist) {
					good_vert = 0;
					break;
				    }
				}

				if (good_vert)
				    break;
			    }
			}
			if (good_vert)
			    break;
		    }
		    if (good_vert)
			break;
		}

		break;
	    }
	case ID_EBM:
	    {
		struct rt_ebm_internal *ebm =
		    (struct rt_ebm_internal *)ip->idb_ptr;
		point_t pnt;

		RT_EBM_CK_MAGIC(ebm);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, ebm->mat, pnt);
		break;
	    }
	case ID_BOT:
	    {
		struct rt_bot_internal *bot =
		    (struct rt_bot_internal *)ip->idb_ptr;

		    VMOVE(mpt, bot->vertices);
		break;
	    }
	case ID_DSP:
	    {
		struct rt_dsp_internal *dsp =
		    (struct rt_dsp_internal *)ip->idb_ptr;
		point_t pnt;

		RT_DSP_CK_MAGIC(dsp);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, dsp->dsp_stom, pnt);
		break;
	    }
	case ID_HF:
	    {
		struct rt_hf_internal *hf =
		    (struct rt_hf_internal *)ip->idb_ptr;

		RT_HF_CK_MAGIC(hf);

		VMOVE(mpt, hf->v);
		break;
	    }
	case ID_VOL:
	    {
		struct rt_vol_internal *vol =
		    (struct rt_vol_internal *)ip->idb_ptr;
		point_t pnt;

		RT_VOL_CK_MAGIC(vol);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, vol->mat, pnt);
		break;
	    }
	case ID_HALF:
	    {
		struct rt_half_internal *haf =
		    (struct rt_half_internal *)ip->idb_ptr;
		RT_HALF_CK_MAGIC(haf);

		VSCALE(mpt, haf->eqn, haf->eqn[H]);
		break;
	    }
	case ID_ARB8:
	    {
		struct rt_arb_internal *arb =
		    (struct rt_arb_internal *)ip->idb_ptr;
		RT_ARB_CK_MAGIC(arb);

		VMOVE(mpt, arb->pt[0]);
		break;
	    }
	case ID_ELL:
	case ID_SPH:
	    {
		struct rt_ell_internal *ell =
		    (struct rt_ell_internal *)ip->idb_ptr;
		RT_ELL_CK_MAGIC(ell);

		VMOVE(mpt, ell->v);
		break;
	    }
	case ID_SUPERELL:
	    {
		struct rt_superell_internal *superell =
		    (struct rt_superell_internal *)ip->idb_ptr;
		RT_SUPERELL_CK_MAGIC(superell);

		VMOVE(mpt, superell->v);
		break;
	    }
	case ID_TOR:
	    {
		struct rt_tor_internal *tor =
		    (struct rt_tor_internal *)ip->idb_ptr;
		RT_TOR_CK_MAGIC(tor);

		VMOVE(mpt, tor->v);
		break;
	    }
	case ID_TGC:
	case ID_REC:
	    {
		struct rt_tgc_internal *tgc =
		    (struct rt_tgc_internal *)ip->idb_ptr;
		RT_TGC_CK_MAGIC(tgc);

		VMOVE(mpt, tgc->v);
		break;
	    }
	case ID_GRIP:
	    {
		struct rt_grip_internal *gip =
		    (struct rt_grip_internal *)ip->idb_ptr;
		RT_GRIP_CK_MAGIC(gip);
		VMOVE(mpt, gip->center);
		break;
	    }
	case ID_ARS:
	    {
		struct rt_ars_internal *ars =
		    (struct rt_ars_internal *)ip->idb_ptr;
		RT_ARS_CK_MAGIC(ars);

		VMOVE(mpt, &ars->curves[0][0]);
		break;
	    }
	case ID_RPC:
	    {
		struct rt_rpc_internal *rpc =
		    (struct rt_rpc_internal *)ip->idb_ptr;
		RT_RPC_CK_MAGIC(rpc);

		VMOVE(mpt, rpc->rpc_V);
		break;
	    }
	case ID_RHC:
	    {
		struct rt_rhc_internal *rhc =
		    (struct rt_rhc_internal *)ip->idb_ptr;
		RT_RHC_CK_MAGIC(rhc);

		VMOVE(mpt, rhc->rhc_V);
		break;
	    }
	case ID_EPA:
	    {
		struct rt_epa_internal *epa =
		    (struct rt_epa_internal *)ip->idb_ptr;
		RT_EPA_CK_MAGIC(epa);

		VMOVE(mpt, epa->epa_V);
		break;
	    }
	case ID_EHY:
	    {
		struct rt_ehy_internal *ehy =
		    (struct rt_ehy_internal *)ip->idb_ptr;
		RT_EHY_CK_MAGIC(ehy);

		VMOVE(mpt, ehy->ehy_V);
		break;
	    }
	case ID_HYP:
	    {
		struct rt_hyp_internal *hyp =
		    (struct rt_hyp_internal *)ip->idb_ptr;
		RT_HYP_CK_MAGIC(hyp);

		VMOVE(mpt, hyp->hyp_Vi);
		break;
	    }
	case ID_ETO:
	    {
		struct rt_eto_internal *eto =
		    (struct rt_eto_internal *)ip->idb_ptr;
		RT_ETO_CK_MAGIC(eto);

		VMOVE(mpt, eto->eto_V);
		break;
	    }
	case ID_POLY:
	    {
		struct rt_pg_face_internal *_poly;
		struct rt_pg_internal *pg =
		    (struct rt_pg_internal *)ip->idb_ptr;
		RT_PG_CK_MAGIC(pg);

		_poly = pg->poly;
		VMOVE(mpt, _poly->verts);
		break;
	    }
	case ID_SKETCH:
	    {
		struct rt_sketch_internal *skt =
		    (struct rt_sketch_internal *)ip->idb_ptr;
		RT_SKETCH_CK_MAGIC(skt);

		VMOVE(mpt, skt->V);
		break;
	    }
	case ID_EXTRUDE:
	    {
		struct rt_extrude_internal *extr =
		    (struct rt_extrude_internal *)ip->idb_ptr;
		RT_EXTRUDE_CK_MAGIC(extr);

		if (extr->skt && extr->skt->verts) {
		    VJOIN2(mpt, extr->V, extr->skt->verts[0][0], extr->u_vec,
			   extr->skt->verts[0][1], extr->v_vec);
		} else {
		    VMOVE(mpt, extr->V);
		}
		break;
	    }
	case ID_NMG:
	    {
		struct vertex *v;
		struct vertexuse *vu;
		struct edgeuse *eu;
		struct loopuse *lu;
		struct faceuse *fu;
		struct shell *s;
		struct nmgregion *r;
		struct model *m =
		    (struct model *) ip->idb_ptr;
		NMG_CK_MODEL(m);

		/* set default first */
		VSETALL(mpt, 0.0);

		if (BU_LIST_IS_EMPTY(&m->r_hd))
		    break;

		r = BU_LIST_FIRST(nmgregion, &m->r_hd);
		if (!r)
		    break;
		NMG_CK_REGION(r);

		if (BU_LIST_IS_EMPTY(&r->s_hd))
		    break;

		s = BU_LIST_FIRST(shell, &r->s_hd);
		if (!s)
		    break;
		NMG_CK_SHELL(s);

		if (BU_LIST_IS_EMPTY(&s->fu_hd))
		    fu = (struct faceuse *)NULL;
		else
		    fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
		if (fu) {
		    NMG_CK_FACEUSE(fu);
		    lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
		    NMG_CK_LOOPUSE(lu);
		    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
			eu = BU_LIST_FIRST(edgeuse, &lu->down_hd);
			NMG_CK_EDGEUSE(eu);
			NMG_CK_VERTEXUSE(eu->vu_p);
			v = eu->vu_p->v_p;
		    } else {
			vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
			NMG_CK_VERTEXUSE(vu);
			v = vu->v_p;
		    }
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		if (BU_LIST_IS_EMPTY(&s->lu_hd))
		    lu = (struct loopuse *)NULL;
		else
		    lu = BU_LIST_FIRST(loopuse, &s->lu_hd);
		if (lu) {
		    NMG_CK_LOOPUSE(lu);
		    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
			eu = BU_LIST_FIRST(edgeuse, &lu->down_hd);
			NMG_CK_EDGEUSE(eu);
			NMG_CK_VERTEXUSE(eu->vu_p);
			v = eu->vu_p->v_p;
		    } else {
			vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
			NMG_CK_VERTEXUSE(vu);
			v = vu->v_p;
		    }
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		if (BU_LIST_IS_EMPTY(&s->eu_hd))
		    eu = (struct edgeuse *)NULL;
		else
		    eu = BU_LIST_FIRST(edgeuse, &s->eu_hd);
		if (eu) {
		    NMG_CK_EDGEUSE(eu);
		    NMG_CK_VERTEXUSE(eu->vu_p);
		    v = eu->vu_p->v_p;
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		vu = s->vu_p;
		if (vu) {
		    NMG_CK_VERTEXUSE(vu);
		    v = vu->v_p;
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
	    }
	default:
	    VSETALL(mpt, 0.0);
	    bu_vls_printf(gedp->ged_result_str,
			  "get_solid_keypoint: unrecognized solid type");
	    return GED_ERROR;
    }
    MAT4X3PNT(pt, mat, mpt);
    return GED_OK;
}
示例#4
0
extern "C" void
rt_sketch_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *UNUSED(tol))
{
    struct rt_sketch_internal *eip;

    RT_CK_DB_INTERNAL(ip);
    eip = (struct rt_sketch_internal *)ip->idb_ptr;
    RT_SKETCH_CK_MAGIC(eip);

    ON_3dPoint plane_origin;
    ON_3dVector plane_x_dir, plane_y_dir;

    //  Find plane in 3 space corresponding to the sketch.

    plane_origin = ON_3dPoint(eip->V);
    plane_x_dir = ON_3dVector(eip->u_vec);
    plane_y_dir = ON_3dVector(eip->v_vec);
    const ON_Plane sketch_plane = ON_Plane(plane_origin, plane_x_dir, plane_y_dir);

    //  For the brep, need the list of 3D vertex points.  In sketch, they
    //  are stored as 2D coordinates, so use the sketch_plane to define 3 space
    //  points for the vertices.
    for (size_t i = 0; i < eip->vert_count; i++) {
	(*b)->NewVertex(sketch_plane.PointAt(eip->verts[i][0], eip->verts[i][1]), 0.0);
    }

    // Create the brep elements corresponding to the sketch lines, curves
    // and bezier segments. Create 2d, 3d and BrepEdge elements for each segment.
    // Will need to use the bboxes of each element to
    // build the overall bounding box for the face. Use bGrowBox to expand
    // a single box.
    struct line_seg *lsg;
    struct carc_seg *csg;
    struct bezier_seg *bsg;
    uint32_t *lng;
    for (size_t i = 0; i < (&eip->curve)->count; i++) {
	lng = (uint32_t *)(&eip->curve)->segment[i];
	switch (*lng) {
	    case CURVE_LSEG_MAGIC:
		{
		    lsg = (struct line_seg *)lng;
		    ON_Curve* lsg3d = new ON_LineCurve((*b)->m_V[lsg->start].Point(), (*b)->m_V[lsg->end].Point());
		    lsg3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(lsg3d);
		}
		break;
	    case CURVE_CARC_MAGIC:
		csg = (struct carc_seg *)lng;
		if (csg->radius < 0) {
		    ON_3dPoint cntrpt = (*b)->m_V[csg->end].Point();
		    ON_3dPoint edgept = (*b)->m_V[csg->start].Point();
		    ON_Plane cplane = ON_Plane(cntrpt, plane_x_dir, plane_y_dir);
		    ON_Circle c3dcirc = ON_Circle(cplane, cntrpt.DistanceTo(edgept));
		    ON_Curve* c3d = new ON_ArcCurve((const ON_Circle)c3dcirc);
		    c3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(c3d);
		} else {
		    // need to calculated 3rd point on arc - look to sketch.c around line 581 for
		    // logic
		}
		break;
	    case CURVE_BEZIER_MAGIC:
		bsg = (struct bezier_seg *)lng;
		{
		    ON_3dPointArray bezpoints(bsg->degree + 1);
		    for (int j = 0; j < bsg->degree + 1; j++) {
			bezpoints.Append((*b)->m_V[bsg->ctl_points[j]].Point());
		    }
		    ON_BezierCurve bez3d = ON_BezierCurve((const ON_3dPointArray)bezpoints);
		    ON_NurbsCurve* beznurb3d = ON_NurbsCurve::New();
		    bez3d.GetNurbForm(*beznurb3d);
		    beznurb3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(beznurb3d);
		}
		break;
	    default:
		bu_log("Unhandled sketch object\n");
		break;
	}
    }

    // Create the plane surface and brep face.
    ON_PlaneSurface *sketch_surf = new ON_PlaneSurface(sketch_plane);
    (*b)->m_S.Append(sketch_surf);
    int surfindex = (*b)->m_S.Count();
    ON_BrepFace& face = (*b)->NewFace(surfindex - 1);

    // For the purposes of BREP creation, it is necessary to identify
    // loops created by sketch segments.  This information is not stored
    // in the sketch data structures themselves, and thus must be deduced
    FindLoops(b);
    const ON_BrepLoop* tloop = (*b)->m_L.First();
    sketch_surf->SetDomain(0, tloop->m_pbox.m_min.x, tloop->m_pbox.m_max.x);
    sketch_surf->SetDomain(1, tloop->m_pbox.m_min.y, tloop->m_pbox.m_max.y);
    sketch_surf->SetExtents(0, sketch_surf->Domain(0));
    sketch_surf->SetExtents(1, sketch_surf->Domain(1));
    (*b)->SetTrimIsoFlags(face);
    (*b)->FlipFace(face);
    (*b)->Compact();
}
示例#5
0
extern "C" void
rt_revolve_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol)
{
    struct rt_db_internal *tmp_internal;
    struct rt_revolve_internal *rip;
    struct rt_sketch_internal *eip;

    BU_ALLOC(tmp_internal, struct rt_db_internal);
    RT_DB_INTERNAL_INIT(tmp_internal);

    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    RT_REVOLVE_CK_MAGIC(rip);
    eip = rip->skt;
    RT_SKETCH_CK_MAGIC(eip);

    ON_3dPoint plane_origin;
    ON_3dVector plane_x_dir, plane_y_dir;

    bool full_revolve = true;
    if (rip->ang < 2*ON_PI && rip->ang > 0)
	full_revolve = false;

    //  Find plane in 3 space corresponding to the sketch.

    vect_t startpoint;
    VADD2(startpoint, rip->v3d, rip->r);
    plane_origin = ON_3dPoint(startpoint);
    plane_x_dir = ON_3dVector(eip->u_vec);
    plane_y_dir = ON_3dVector(eip->v_vec);
    const ON_Plane sketch_plane = ON_Plane(plane_origin, plane_x_dir, plane_y_dir);

    //  For the brep, need the list of 3D vertex points.  In sketch, they
    //  are stored as 2D coordinates, so use the sketch_plane to define 3 space
    //  points for the vertices.
    for (size_t i = 0; i < eip->vert_count; i++) {
	(*b)->NewVertex(sketch_plane.PointAt(eip->verts[i][0], eip->verts[i][1]), 0.0);
    }

    // Create the brep elements corresponding to the sketch lines, curves
    // and bezier segments. Create 2d, 3d and BrepEdge elements for each segment.
    // Will need to use the bboxes of each element to
    // build the overall bounding box for the face. Use bGrowBox to expand
    // a single box.
    struct line_seg *lsg;
    struct carc_seg *csg;
    struct bezier_seg *bsg;
    uint32_t *lng;
    for (size_t i = 0; i < (&eip->curve)->count; i++) {
	lng = (uint32_t *)(&eip->curve)->segment[i];
	switch (*lng) {
	    case CURVE_LSEG_MAGIC: {
		lsg = (struct line_seg *)lng;
		ON_Curve* lsg3d = new ON_LineCurve((*b)->m_V[lsg->start].Point(), (*b)->m_V[lsg->end].Point());
		lsg3d->SetDomain(0.0, 1.0);
		(*b)->m_C3.Append(lsg3d);
	    }
		break;
	    case CURVE_CARC_MAGIC:
		csg = (struct carc_seg *)lng;
		if (csg->radius < 0) { {
		    ON_3dPoint cntrpt = (*b)->m_V[csg->end].Point();
		    ON_3dPoint edgept = (*b)->m_V[csg->start].Point();
		    ON_Plane cplane = ON_Plane(cntrpt, plane_x_dir, plane_y_dir);
		    ON_Circle c3dcirc = ON_Circle(cplane, cntrpt.DistanceTo(edgept));
		    ON_Curve* c3d = new ON_ArcCurve((const ON_Circle)c3dcirc);
		    c3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(c3d);
		}
		} else {
		    // need to calculated 3rd point on arc - look to sketch.c around line 581 for
		    // logic
		}
		break;
	    case CURVE_BEZIER_MAGIC:
		bsg = (struct bezier_seg *)lng;
		{
		    ON_3dPointArray bezpoints = ON_3dPointArray(bsg->degree + 1);
		    for (int j = 0; j < bsg->degree + 1; j++) {
			bezpoints.Append((*b)->m_V[bsg->ctl_points[j]].Point());
		    }
		    ON_BezierCurve bez3d = ON_BezierCurve((const ON_3dPointArray)bezpoints);
		    ON_NurbsCurve* beznurb3d = ON_NurbsCurve::New();
		    bez3d.GetNurbForm(*beznurb3d);
		    beznurb3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(beznurb3d);
		}
		break;
	    default:
		bu_log("Unhandled sketch object\n");
		break;
	}
    }

    vect_t endpoint;
    VADD2(endpoint, rip->v3d, rip->axis3d);
    const ON_Line& revaxis = ON_Line(ON_3dPoint(rip->v3d), ON_3dPoint(endpoint));

    FindLoops(b, &revaxis, rip->ang);

    // Create the two boundary surfaces, if it's not a full revolution
    if (!full_revolve) {
	// First, deduce the transformation matrices to calculate the position of the end surface
	// The transformation matrices are to rotate an arbitrary point around an arbitrary axis
	// Let the point A = (x, y, z), the rotation axis is p1p2 = (x2,y2,z2)-(x1,y1,z1) = (a,b,c)
	// Then T1 is to translate p1 to the origin
	// Rx is to rotate p1p2 around the X axis to the plane XOZ
	// Ry is to rotate p1p2 around the Y axis to be coincident to Z axis
	// Rz is to rotate A with the angle around Z axis (the new p1p2)
	// RxInv, RyInv, T1Inv are the inverse transformation of Rx, Ry, T1, respectively.
	// The whole transformation is A' = A*T1*Rx*Ry*Rz*Ry*Inv*Rx*Inv = A*R
	vect_t end_plane_origin, end_plane_x_dir, end_plane_y_dir;
	mat_t R;
	MAT_IDN(R);
	mat_t T1, Rx, Ry, Rz, RxInv, RyInv, T1Inv;
	MAT_IDN(T1);
	VSET(&T1[12], -rip->v3d[0], -rip->v3d[1], -rip->v3d[2]);
	MAT_IDN(Rx);
	fastf_t v = sqrt(rip->axis3d[1]*rip->axis3d[1]+rip->axis3d[2]*rip->axis3d[2]);
	VSET(&Rx[4], 0, rip->axis3d[2]/v, rip->axis3d[1]/v);
	VSET(&Rx[8], 0, -rip->axis3d[1]/v, rip->axis3d[2]/v);
	MAT_IDN(Ry);
	fastf_t u = MAGNITUDE(rip->axis3d);
	VSET(&Ry[0], v/u, 0, -rip->axis3d[0]/u);
	VSET(&Ry[8], rip->axis3d[0]/u, 0, v/u);
	MAT_IDN(Rz);
	fastf_t C, S;
	C = cos(rip->ang);
	S = sin(rip->ang);
	VSET(&Rz[0], C, S, 0);
	VSET(&Rz[4], -S, C, 0);
	bn_mat_inv(RxInv, Rx);
	bn_mat_inv(RyInv, Ry);
	bn_mat_inv(T1Inv, T1);
	mat_t temp;
	bn_mat_mul4(temp, T1, Rx, Ry, Rz);
	bn_mat_mul4(R, temp, RyInv, RxInv, T1Inv);
	VEC3X3MAT(end_plane_origin, plane_origin, R);
	VADD2(end_plane_origin, end_plane_origin, &R[12]);
	VEC3X3MAT(end_plane_x_dir, plane_x_dir, R);
	VEC3X3MAT(end_plane_y_dir, plane_y_dir, R);

	// Create the start and end surface with rt_sketch_brep()
	struct rt_sketch_internal sketch;
	sketch = *(rip->skt);
	ON_Brep *b1 = ON_Brep::New();
	VMOVE(sketch.V, plane_origin);
	VMOVE(sketch.u_vec, plane_x_dir);
	VMOVE(sketch.v_vec, plane_y_dir);
	tmp_internal->idb_ptr = (void *)(&sketch);
	rt_sketch_brep(&b1, tmp_internal, tol);
	(*b)->Append(*b1->Duplicate());

	ON_Brep *b2 = ON_Brep::New();
	VMOVE(sketch.V, end_plane_origin);
	VMOVE(sketch.u_vec, end_plane_x_dir);
	VMOVE(sketch.v_vec, end_plane_y_dir);
	tmp_internal->idb_ptr = (void *)(&sketch);
	rt_sketch_brep(&b2, tmp_internal, tol);
	(*b)->Append(*b2->Duplicate());
	(*b)->FlipFace((*b)->m_F[(*b)->m_F.Count()-1]);
    }
    bu_free(tmp_internal, "free temporary rt_db_internal");
}
示例#6
0
/**
 * R T _ S K E T C H _ S U R F _ A R E A
 *
 * calculate approximate surface area for a sketch primitive by iterating through
 * each curve segment in the sketch, calculating the area of the polygon
 * created by the start and end points of each curve segment, as well as the
 * additional areas for circular segments.
 *
 * line_seg: calculate the area for the polygon edge Start->End
 * carc_seg: if the segment is a full circle, calculate its area.
 *      else, calculate the area for the polygon edge Start->End, and the area
 *      of the circular segment
 * bezier_seg: approximate the bezier using the bezier_to_carcs() function. for
 *      each carc_seg, calculate the area for the polygon edges Start->End and
 *      the area of the circular segment
 */
extern "C" void
rt_sketch_surf_area(fastf_t *area, const struct rt_db_internal *ip)
{
    int j;
    size_t i;
    fastf_t poly_area = 0, carc_area = 0;

    struct bn_tol tol;
    struct rt_sketch_internal *sketch_ip = (struct rt_sketch_internal *)ip->idb_ptr;
    RT_SKETCH_CK_MAGIC(sketch_ip);
    struct rt_curve crv = sketch_ip->curve;

    // a sketch with no curves has no area
    if (UNLIKELY(crv.count == 0)) {
	return;
    }

    tol.magic = BN_TOL_MAGIC;
    tol.dist = RT_DOT_TOL;
    tol.dist_sq = RT_DOT_TOL * RT_DOT_TOL;

    // iterate through each curve segment in the sketch
    for (i = 0; i < crv.count; i++) {
	const struct line_seg *lsg;
	const struct carc_seg *csg;
	const struct bezier_seg *bsg;

	const uint32_t *lng = (uint32_t *)crv.segment[i];

	switch (*lng) {
	case CURVE_LSEG_MAGIC:
	    lsg = (struct line_seg *)lng;
	    // calculate area for polygon edge
	    poly_area += V2CROSS(SKETCH_PT(lsg->start), SKETCH_PT(lsg->end));
	    break;
	case CURVE_CARC_MAGIC:
	    csg = (struct carc_seg *)lng;
	    if (csg->radius < 0) {
		// calculate full circle area
		carc_area += M_PI * DIST_PT2D_PT2D_SQ(SKETCH_PT(csg->start), SKETCH_PT(csg->end));
	    } else {
		fastf_t theta, side_ratio;
		// calculate area for polygon edge
		poly_area += V2CROSS(SKETCH_PT(csg->start), SKETCH_PT(csg->end));
		// calculate area for circular segment
		side_ratio = DIST_PT2D_PT2D(SKETCH_PT(csg->start), SKETCH_PT(csg->end)) / (2.0 * csg->radius);
		theta = asin(side_ratio);
		carc_area += 0.5 * csg->radius * csg->radius * (theta - side_ratio);
	    }
	    break;
	case CURVE_BEZIER_MAGIC: {
	    bsg = (struct bezier_seg *)lng;
	    ON_2dPointArray bez_pts(bsg->degree + 1);
	    std::vector<ON_Arc> carcs;
	    // convert struct bezier_seg into ON_BezierCurve
	    for (j = 0; j < bsg->degree + 1; j++) {
		bez_pts.Append(SKETCH_PT(bsg->ctl_points[j]));
	    }
	    // approximate bezier curve by a set of circular arcs
	    bezier_to_carcs(ON_BezierCurve(bez_pts), &tol, carcs);
	    for (std::vector<ON_Arc>::iterator it = carcs.begin(); it != carcs.end(); ++it) {
		// calculate area for each polygon edge
		poly_area += V2CROSS(it->StartPoint(), it->EndPoint());
		// calculate area for each circular segment
		carc_area += 0.5 * it->Radius() * it->Radius() * (it->AngleRadians() - sin(it->AngleRadians()));
	    }
	    }
	    break;
	case CURVE_NURB_MAGIC:
	default:
	    break;
	}
    }
    *area = 0.5 * fabs(poly_area) + carc_area;
}