void
Do_subfigs()
{
    int i, j;
    int entity_type;
    struct wmember head1;
    struct wmember *wmem;

    if (RT_G_DEBUG & DEBUG_MEM_FULL)
	bu_mem_barriercheck();

    BU_LIST_INIT(&head1.l);

    for (i = 0; i < totentities; i++) {
	int subfigdef_de;
	int subfigdef_index;
	int no_of_members;
	int *members;
	char *name = NULL;
	struct wmember head2;
	double mat_scale[3];
	int non_unit;

	if (dir[i]->type != 408)
	    continue;

	if (RT_G_DEBUG & DEBUG_MEM_FULL)
	    bu_mem_barriercheck();

	if (dir[i]->param <= pstart) {
	    bu_log("Illegal parameter pointer for entity D%07d (%s)\n" ,
		   dir[i]->direct, dir[i]->name);
	    continue;
	}

	Readrec(dir[i]->param);
	Readint(&entity_type, "");
	if (entity_type != 408) {
	    bu_log("Expected Singular Subfigure Instance Entity, found %s\n",
		   iges_type(entity_type));
	    continue;
	}

	Readint(&subfigdef_de, "");
	subfigdef_index = (subfigdef_de - 1)/2;
	if (subfigdef_index >= totentities) {
	    bu_log("Singular Subfigure Instance Entity gives Subfigure Definition");
	    bu_log("\tEntity DE of %d, largest DE in file is %d\n",
		   subfigdef_de, (totentities * 2) - 1);
	    continue;
	}
	if (dir[subfigdef_index]->type != 308) {
	    bu_log("Expected Subfigure Definition Entity, found %s\n",
		   iges_type(dir[subfigdef_index]->type));
	    continue;
	}

	if (dir[subfigdef_index]->param <= pstart) {
	    bu_log("Illegal parameter pointer for entity D%07d (%s)\n" ,
		   dir[subfigdef_index]->direct, dir[subfigdef_index]->name);
	    continue;
	}
	Readrec(dir[subfigdef_index]->param);
	Readint(&entity_type, "");
	if (entity_type != 308) {
	    bu_log("Expected Subfigure Definition Entity, found %s\n",
		   iges_type(entity_type));
	    continue;
	}

	Readint(&j, "");	/* ignore depth */
	Readstrg("");		/* ignore subfigure name */

	wmem = mk_addmember(dir[subfigdef_index]->name, &head1.l, NULL, WMOP_UNION);
	non_unit = 0;
	for (j = 0; j < 3; j++) {
	    double mag_sq;

	    mat_scale[j] = 1.0;
	    mag_sq = MAGSQ(&(*dir[i]->rot)[j*4]);

	    /* FIXME: arbitrary undefined tolerance */
	    if (!NEAR_EQUAL(mag_sq, 1.0, 100.0*SQRT_SMALL_FASTF)) {
		mat_scale[j] = 1.0/sqrt(mag_sq);
		non_unit = 1;
	    }
	}

	if (non_unit) {
	    bu_log("Illegal transformation matrix in %s for member %s\n",
		   curr_file->obj_name, wmem->wm_name);
	    bu_log(" row vector magnitudes are %g, %g, and %g\n",
		   1.0/mat_scale[0], 1.0/mat_scale[1], 1.0/mat_scale[2]);
	    bn_mat_print("", *dir[i]->rot);
	    for (j = 0; j < 11; j++) {
		if ((j+1)%4 == 0)
		    continue;
		(*dir[i]->rot)[j] *= mat_scale[0];
	    }
	    bn_mat_print("After scaling:", *dir[i]->rot);

	}
	memcpy(wmem->wm_mat, *dir[i]->rot, sizeof(mat_t));

	Readint(&no_of_members, "");	/* get number of members */
	members = (int *)bu_calloc(no_of_members, sizeof(int), "Do_subfigs: members");
	for (j = 0; j < no_of_members; j++)
	    Readint(&members[j], "");

	BU_LIST_INIT(&head2.l);
	for (j = 0; j < no_of_members; j++) {
	    int idx;

	    idx = (members[j] - 1)/2;

	    if (idx >= totentities) {
		bu_log("Subfigure Definition Entity gives Member Entity");
		bu_log("\tDE of %d, largest DE in file is %d\n",
		       members[j], (totentities * 2) - 1);
		continue;
	    }
	    if (dir[idx]->param <= pstart) {
		bu_log("Illegal parameter pointer for entity D%07d (%s)\n" ,
		       dir[idx]->direct, dir[idx]->name);
		continue;
	    }

	    if (dir[idx]->type == 416) {
		struct file_list *list_ptr;
		char *file_name;
		int found = 0;

		/* external reference */

		Readrec(dir[idx]->param);
		Readint(&entity_type, "");

		if (entity_type != 416) {
		    bu_log("Expected External reference Entity, found %s\n",
			   iges_type(entity_type));
		    continue;
		}

		if (dir[idx]->form != 1) {
		    bu_log("External Reference Entity of form #%d found\n",
			   dir[idx]->form);
		    bu_log("\tOnly form #1 is currently handled\n");
		    continue;
		}

		Readname(&file_name, "");

		/* Check if this external reference is already on the list */
		for (BU_LIST_FOR(list_ptr, file_list, &iges_list.l)) {
		    if (BU_STR_EQUAL(file_name, list_ptr->file_name)) {
			found = 1;
			name = list_ptr->obj_name;
			break;
		    }
		}

		if (!found) {
		    /* Need to add this one to the list */
		    BU_ALLOC(list_ptr, struct file_list);

		    list_ptr->file_name = file_name;
		    if (no_of_members == 1)
			bu_strlcpy(list_ptr->obj_name, dir[subfigdef_index]->name, NAMESIZE+1);
		    else {
			bu_strlcpy(list_ptr->obj_name, "subfig", NAMESIZE+1);
			(void) Make_unique_brl_name(list_ptr->obj_name);
		    }


		    BU_LIST_APPEND(&curr_file->l, &list_ptr->l);

		    name = list_ptr->obj_name;
		} else
		    bu_free((char *)file_name, "Do_subfigs: file_name");

	    } else
		name = dir[idx]->name;

	    if (no_of_members > 1) {
		wmem = mk_addmember(name, &head2.l, NULL, WMOP_UNION);
		memcpy(wmem->wm_mat, dir[idx]->rot, sizeof(mat_t));
	    }
	}

	if (no_of_members > 1)
	    (void)mk_lcomb(fdout, dir[subfigdef_index]->name, &head2, 0,
			   (char *)NULL, (char *)NULL, (unsigned char *)NULL, 0);
    }
Пример #2
0
struct edge_g_cnurb *
Get_cnurb_curve(int curve_de, int *linear)
{
    int i;
    int curve;
    struct edge_g_cnurb *crv;

    *linear = 0;

    curve = (curve_de - 1)/2;
    if (curve >= dirarraylen) {
	bu_log("Get_cnurb_curve: DE=%d is too large, dirarraylen = %d\n", curve_de, dirarraylen);
	return (struct edge_g_cnurb *)NULL;
    }

    switch (dir[curve]->type) {
	case 110: {
	    /* line */
	    int pt_type;
	    int type;
	    point_t pt1;
	    point_t start_pt, end_pt;

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Get_cnurb_curve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		return (struct edge_g_cnurb *)NULL;

	    }
	    /* Read first point */
	    for (i = 0; i < 3; i++)
		Readcnv(&pt1[i], "");
	    MAT4X3PNT(start_pt, *dir[curve]->rot, pt1);

	    /* Read second point */
	    for (i = 0; i < 3; i++)
		Readcnv(&pt1[i], "");
	    MAT4X3PNT(end_pt, *dir[curve]->rot, pt1);

	    /* pt_type for rational UVW coords */
	    pt_type = RT_NURB_MAKE_PT_TYPE(3, 3, 1);

	    /* make a linear edge_g_cnurb (order=2) */
	    crv = rt_nurb_new_cnurb(2, 4, 2, pt_type);

	    /* insert control mesh */
	    VMOVE(crv->ctl_points, start_pt);
	    VMOVE(&crv->ctl_points[3], end_pt);

	    /* insert knot values */
	    crv->k.knots[0] = 0.0;
	    crv->k.knots[1] = 0.0;
	    crv->k.knots[2] = 1.0;
	    crv->k.knots[3] = 1.0;

	    *linear = 1;

	    return crv;
	}
	case 126:	/* B-spline */
	    crv = Get_cnurb(curve);
	    if (crv->order < 3)
		*linear = 1;
	    return crv;
	default:
	    bu_log("Not yet handling curves of type: %s\n", iges_type(dir[curve]->type));
	    break;
    }

    return (struct edge_g_cnurb *)NULL;
}
struct faceuse *
Make_planar_face(struct shell *s, int entityno, int face_orient)
{

    int sol_num;	/* IGES solid type number */
    int no_of_edges;	/* edge count for this loop */
    int no_of_param_curves;
    int vert_count = 0;	/* Actual number of vertices used to make face */
    struct iges_edge_use *edge_list;	/* list of edgeuses from iges loop entity */
    struct faceuse *fu = NULL;	/* NMG face use */
    struct loopuse *lu;		/* NMG loop use */
    struct vertex ***verts;	/* list of vertices */
    struct iges_vertex_list *v_list;
    int done;
    int i, j, k;

    /* Acquiring Data */

    if (dir[entityno]->param <= pstart) {
	bu_log("Illegal parameter pointer for entity D%07d (%s)\n" ,
	       dir[entityno]->direct, dir[entityno]->name);
	return 0;
    }

    Readrec(dir[entityno]->param);
    Readint(&sol_num, "");
    if (sol_num != 508) {
	bu_exit(1, "ERROR: Entity #%d is not a loop (it's a %s)\n", entityno, iges_type(sol_num));
    }

    Readint(&no_of_edges, "");
    edge_list = (struct iges_edge_use *)bu_calloc(no_of_edges, sizeof(struct iges_edge_use) ,
						  "Make_face (edge_list)");
    for (i = 0; i < no_of_edges; i++) {
	Readint(&edge_list[i].edge_is_vertex, "");
	Readint(&edge_list[i].edge_de, "");
	Readint(&edge_list[i].index, "");
	Readint(&edge_list[i].orient, "");
	if (!face_orient) {
	    /* need opposite orientation of edge */
	    if (edge_list[i].orient)
		edge_list[i].orient = 0;
	    else
		edge_list[i].orient = 1;
	}
	edge_list[i].root = (struct iges_param_curve *)NULL;
	Readint(&no_of_param_curves, "");
	for (j = 0; j < no_of_param_curves; j++) {
	    struct iges_param_curve *new_crv;
	    struct iges_param_curve *crv;

	    Readint(&k, "");	/* ignore iso-parametric flag */

	    BU_ALLOC(new_crv, struct iges_param_curve);
	    if (edge_list[i].root == (struct iges_param_curve *)NULL)
		edge_list[i].root = new_crv;
	    else {
		crv = edge_list[i].root;
		while (crv->next != (struct iges_param_curve *)NULL)
		    crv = crv->next;
		crv->next = new_crv;
	    }
	    Readint(&new_crv->curve_de, "");
	    new_crv->next = (struct iges_param_curve *)NULL;
	}
    }

    verts = (struct vertex ***)bu_calloc(no_of_edges, sizeof(struct vertex **) ,
					 "Make_face: vertex_list **");

    for (i = 0; i < no_of_edges; i++) {
	if (face_orient)
	    verts[i] = Get_vertex(&edge_list[i]);
	else
	    verts[no_of_edges-1-i] = Get_vertex(&edge_list[i]);
    }

    /* eliminate zero length edges */
    vert_count = no_of_edges;
    done = 0;
    while (!done) {
	done = 1;
	for (i = 0; i < vert_count; i++) {
	    k = i + 1;
	    if (k == vert_count)
		k = 0;

	    if (verts[i] == verts[k]) {
		bu_log("Ignoring zero length edge\n");
		done = 0;
		vert_count--;
		for (j = i; j < vert_count; j++)
		    verts[j] = verts[j+1];
	    }
	}
    }

    if (vert_count) {
	plane_t pl;		/* Plane equation for face */
	fastf_t area;		/* area of loop */
	fastf_t dist;
	vect_t min2max;
	point_t outside_pt;

	fu = nmg_cmface(s, verts, vert_count);

	/* associate geometry */
	v_list = vertex_root;
	while (v_list != NULL) {
	    for (i = 0; i < v_list->no_of_verts; i++) {
		if (v_list->i_verts[i].v != NULL && v_list->i_verts[i].v->vg_p == NULL) {
		    NMG_CK_VERTEX(v_list->i_verts[i].v);
		    nmg_vertex_gv(v_list->i_verts[i].v ,
				  v_list->i_verts[i].pt);
		}
	    }
	    v_list = v_list->next;
	}

	lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
	NMG_CK_LOOPUSE(lu);

	area = nmg_loop_plane_area(lu, pl);
	if (area < 0.0) {
	    bu_log("Could not calculate area for face (entityno = %d)\n", entityno);
	    nmg_pr_fu_briefly(fu, "");
	    nmg_kfu(fu);
	    fu = (struct faceuse *)NULL;
	    goto err;
	}

	nmg_face_g(fu, pl);
	nmg_face_bb(fu->f_p, &tol);

	/* find a point that is surely outside the loop */
	VSUB2(min2max, fu->f_p->max_pt, fu->f_p->min_pt);
	VADD2(outside_pt, fu->f_p->max_pt, min2max);

	/* move it to the plane of the face */
	dist = DIST_PT_PLANE(outside_pt, pl);
	VJOIN1(outside_pt, outside_pt, -dist, pl);

	if (nmg_class_pt_lu_except(outside_pt, lu, (struct edge *)NULL, &tol) != NMG_CLASS_AoutB) {
	    nmg_reverse_face(fu);
	    if (fu->orientation != OT_SAME) {
		fu = fu->fumate_p;
		if (fu->orientation != OT_SAME)
		    bu_exit(1, "ERROR: no OT_SAME use for a face!\n");
	    }
	}
    } else
	bu_log("No edges left!\n");

err:
    bu_free((char *)edge_list, "Make_face (edge_list)");
    bu_free((char *)verts, "Make_face (vertexlist)");
    return fu;
}