void bn_wrt_point_direc(mat_t out, const mat_t change, const mat_t in, const point_t point, const vect_t direc, const struct bn_tol *tol) { static mat_t t1; static mat_t pt_to_origin, origin_to_pt; static mat_t d_to_zaxis, zaxis_to_d; static vect_t zaxis; /* build "point to origin" matrix */ MAT_IDN(pt_to_origin); MAT_DELTAS_VEC_NEG(pt_to_origin, point); /* build "origin to point" matrix */ MAT_IDN(origin_to_pt); MAT_DELTAS_VEC_NEG(origin_to_pt, point); /* build "direc to zaxis" matrix */ VSET(zaxis, 0.0, 0.0, 1.0); bn_mat_fromto(d_to_zaxis, direc, zaxis, tol); /* build "zaxis to direc" matrix */ bn_mat_inv(zaxis_to_d, d_to_zaxis); /* apply change matrix... * t1 = change * d_to_zaxis * pt_to_origin * in */ bn_mat_mul4(t1, change, d_to_zaxis, pt_to_origin, in); /* apply origin_to_pt matrix: * out = origin_to_pt * zaxis_to_d * * change * d_to_zaxis * pt_to_origin * in */ bn_mat_mul3(out, origin_to_pt, zaxis_to_d, t1); }
/* * M A K E _ N T S C _ X Y Z 2 R G B * * Create the map from * CIE XYZ perceptual space into * an idealized RGB space assuming NTSC primaries with D6500 white. * Only high-quality television-studio monitors are like this, but... */ void make_ntsc_xyz2rgb(fastf_t *xyz2rgb) { mat_t rgb2xyz; point_t tst, newpt; if (rt_clr__cspace_to_xyz(rgb_NTSC, rgb2xyz) == 0) bu_exit(EXIT_FAILURE, "make_ntsc_xyz2rgb() can't initialize color space\n"); bn_mat_inv(xyz2rgb, rgb2xyz); #if 1 /* Verify that it really works, I'm a skeptic */ VSET(tst, 1, 1, 1); MAT3X3VEC(newpt, rgb2xyz, tst); VPRINT("white_rgb (i)", tst); VPRINT("white_xyz (o)", newpt); VSET(tst, 0.313, 0.329, 0.358); MAT3X3VEC(newpt, xyz2rgb, tst); VPRINT("white_xyz (i)", tst); VPRINT("white_rgb (o)", newpt); VSET(tst, 1, 0, 0); MAT3X3VEC(newpt, rgb2xyz, tst); VPRINT("red_rgb (i)", tst); VPRINT("red_xyz (o)", newpt); VSET(tst, 0.670, 0.330, 0.000); MAT3X3VEC(newpt, xyz2rgb, tst); VPRINT("red_xyz (i)", tst); VPRINT("red_rgb (o)", newpt); VSET(tst, 0, 1, 0); MAT3X3VEC(newpt, rgb2xyz, tst); VPRINT("grn_rgb (i)", tst); VPRINT("grn_xyz (o)", newpt); VSET(tst, 0.210, 0.710, 0.080); MAT3X3VEC(newpt, xyz2rgb, tst); VPRINT("grn_xyz (i)", tst); VPRINT("grn_rgb (o)", newpt); VSET(tst, 0, 0, 1); MAT3X3VEC(newpt, rgb2xyz, tst); VPRINT("blu_rgb (i)", tst); VPRINT("blu_xyz (o)", newpt); VSET(tst, 0.140, 0.080, 0.780); MAT3X3VEC(newpt, xyz2rgb, tst); VPRINT("blu_xyz (i)", tst); VPRINT("blu_rgb (o)", newpt); #endif }
void ged_view_update(struct ged_view *gvp) { vect_t work, work1; vect_t temp, temp1; if (!gvp) return; bn_mat_mul(gvp->gv_model2view, gvp->gv_rotation, gvp->gv_center); gvp->gv_model2view[15] = gvp->gv_scale; bn_mat_inv(gvp->gv_view2model, gvp->gv_model2view); /* Find current azimuth, elevation, and twist angles */ VSET(work, 0.0, 0.0, 1.0); /* view z-direction */ MAT4X3VEC(temp, gvp->gv_view2model, work); VSET(work1, 1.0, 0.0, 0.0); /* view x-direction */ MAT4X3VEC(temp1, gvp->gv_view2model, work1); /* calculate angles using accuracy of 0.005, since display * shows 2 digits right of decimal point */ bn_aet_vec(&gvp->gv_aet[0], &gvp->gv_aet[1], &gvp->gv_aet[2], temp, temp1, (fastf_t)0.005); /* Force azimuth range to be [0, 360] */ if ((NEAR_EQUAL(gvp->gv_aet[1], 90.0, (fastf_t)0.005) || NEAR_EQUAL(gvp->gv_aet[1], -90.0, (fastf_t)0.005)) && gvp->gv_aet[0] < 0 && !NEAR_ZERO(gvp->gv_aet[0], (fastf_t)0.005)) gvp->gv_aet[0] += 360.0; else if (NEAR_ZERO(gvp->gv_aet[0], (fastf_t)0.005)) gvp->gv_aet[0] = 0.0; /* apply the perspective angle to model2view */ bn_mat_mul(gvp->gv_pmodel2view, gvp->gv_pmat, gvp->gv_model2view); if (gvp->gv_callback) (*gvp->gv_callback)(gvp, gvp->gv_clientData); }
int ged_view2model_vec(struct ged *gedp, int argc, const char *argv[]) { point_t model_vec; point_t view_vec; mat_t inv_Viewrot; double scan[3]; static const char *usage = "x y z"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); if (argc != 4) goto bad; if (sscanf(argv[1], "%lf", &scan[X]) != 1 || sscanf(argv[2], "%lf", &scan[Y]) != 1 || sscanf(argv[3], "%lf", &scan[Z]) != 1) goto bad; /* convert from double to fastf_t */ VMOVE(view_vec, scan); bn_mat_inv(inv_Viewrot, gedp->ged_gvp->gv_rotation); MAT4X3PNT(model_vec, inv_Viewrot, view_vec); bn_encode_vect(gedp->ged_result_str, model_vec); return GED_OK; bad: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; }
bool STEPWrapper::convert(BRLCADWrapper *dot_g) { MAP_OF_PRODUCT_NAME_TO_ENTITY_ID name2id_map; MAP_OF_ENTITY_ID_TO_PRODUCT_NAME id2name_map; MAP_OF_ENTITY_ID_TO_PRODUCT_ID id2productid_map; MAP_OF_PRODUCT_NAME_TO_ENTITY_ID::iterator niter = name2id_map.end(); if (!dot_g) { return false; } this->dotg = dot_g; int num_ents = instance_list->InstanceCount(); for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_shape_definition_representation))) { ShapeDefinitionRepresentation *sdr = dynamic_cast<ShapeDefinitionRepresentation *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (!sdr) { bu_exit(1, "ERROR: unable to allocate a 'ShapeDefinitionRepresentation' entity\n"); } else { int sdr_id = sdr->GetId(); std::string pname = sdr->GetProductName(); int product_id = sdr->GetProductId(); id2productid_map[sdr_id] = product_id; if (pname.empty()) { std::string str = "ShapeDefinitionRepresentation@"; str = dotg->GetBRLCADName(str); id2name_map[sdr_id] = pname; } else { std::string temp = pname; int index = 2; while ((niter=name2id_map.find(temp)) != name2id_map.end()) { temp = pname + "_" + static_cast<ostringstream*>( &(ostringstream() << (index++)) )->str(); } pname = temp; if ((niter=name2id_map.find(pname)) == name2id_map.end()) { id2name_map[sdr_id] = pname; name2id_map[pname] = product_id; id2name_map[product_id] = pname; } } AdvancedBrepShapeRepresentation *aBrep = sdr->GetAdvancedBrepShapeRepresentation(); if (aBrep) { if (pname.empty()) { std::string str = "product@"; pname = dotg->GetBRLCADName(str); id2name_map[aBrep->GetId()] = pname; id2name_map[product_id] = pname; } else { id2name_map[aBrep->GetId()] = pname; id2name_map[product_id] = pname; } id2productid_map[aBrep->GetId()] = product_id; if (Verbose()) { if (!pname.empty()) { std::cerr << std::endl << " Generating Product -" << pname ; } else { std::cerr << std::endl << " Generating Product"; } } LocalUnits::length = aBrep->GetLengthConversionFactor(); LocalUnits::planeangle = aBrep->GetPlaneAngleConversionFactor(); LocalUnits::solidangle = aBrep->GetSolidAngleConversionFactor(); ON_Brep *onBrep = aBrep->GetONBrep(); if (!onBrep) { delete sdr; bu_exit(1, "ERROR: failure creating advanced boundary representation from %s\n", stepfile.c_str()); } else { ON_TextLog tl; if (!onBrep->IsValid(&tl)) { bu_log("WARNING: %s is not valid\n", name.c_str()); } //onBrep->SpSplitClosedFaces(); //ON_Brep *tbrep = TightenBrep(onBrep); mat_t mat; MAT_IDN(mat); Axis2Placement3D *axis = aBrep->GetAxis2Placement3d(); if (axis != NULL) { //assign matrix values double translate_to[3]; const double *toXaxis = axis->GetXAxis(); const double *toYaxis = axis->GetYAxis(); const double *toZaxis = axis->GetZAxis(); mat_t rot_mat; VMOVE(translate_to,axis->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); MAT_IDN(rot_mat); VMOVE(&rot_mat[0], toXaxis); VMOVE(&rot_mat[4], toYaxis); VMOVE(&rot_mat[8], toZaxis); bn_mat_inv(mat, rot_mat); MAT_DELTAS_VEC(mat, translate_to); } dotg->WriteBrep(pname, onBrep,mat); delete onBrep; } } else { // must be an assembly if (pname.empty()) { std::string str = "assembly@"; pname = dotg->GetBRLCADName(str); } ShapeRepresentation *aSR = sdr->GetShapeRepresentation(); if (aSR) { int sr_id = aSR->GetId(); id2name_map[sr_id] = pname; id2name_map[product_id] = pname; id2productid_map[sr_id] = product_id; } } Factory::DeleteObjects(); } } } /* * Pickup BREP related to SHAPE_REPRESENTATION through SHAPE_REPRESENTATION_RELATIONSHIP * * like the following found in OpenBook Part 'C': * #21281=SHAPE_DEFINITION_REPRESENTATION(#21280,#21270); * #21280=PRODUCT_DEFINITION_SHAPE('','SHAPE FOR C.',#21279); * #21279=PRODUCT_DEFINITION('design','',#21278,#21275); * #21278=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('1','LAST_VERSION',#21277,.MADE.); * #21277=PRODUCT('C','C','NOT SPECIFIED',(#21276)); * #21270=SHAPE_REPRESENTATION('',(#21259),#21267); * #21259=AXIS2_PLACEMENT_3D('DANTE_BX_CPU_TOP_1',#21256,#21257,#21258); * #21267=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#21266)) * GLOBAL_UNIT_ASSIGNED_CONTEXT((#21260,#21264,#21265))REPRESENTATION_CONTEXT('ID1','3')); * * #21271=SHAPE_REPRESENTATION_RELATIONSHIP('','',#21270,#21268); * #21268=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#21254),#21267); * #21272=SHAPE_REPRESENTATION_RELATIONSHIP('','',#21270,#21269); * #21269=MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#21255),#21267); * */ for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_shape_representation_relationship))) { ShapeRepresentationRelationship *srr = dynamic_cast<ShapeRepresentationRelationship *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (srr) { ShapeRepresentation *aSR = dynamic_cast<ShapeRepresentation *>(srr->GetRepresentationRelationshipRep_1()); AdvancedBrepShapeRepresentation *aBrep = dynamic_cast<AdvancedBrepShapeRepresentation *>(srr->GetRepresentationRelationshipRep_2()); if (!aBrep) { //try rep_1 aBrep = dynamic_cast<AdvancedBrepShapeRepresentation *>(srr->GetRepresentationRelationshipRep_1()); aSR = dynamic_cast<ShapeRepresentation *>(srr->GetRepresentationRelationshipRep_2()); } if ((aSR) && (aBrep)) { int sr_id = aSR->GetId(); MAP_OF_ENTITY_ID_TO_PRODUCT_ID::iterator it = id2productid_map.find(sr_id); if (it != id2productid_map.end()) { // product found int product_id = (*it).second; int brep_id = aBrep->GetId(); it = id2productid_map.find(brep_id); if (it == id2productid_map.end()) { // brep not loaded yet so lets do that here. string pname = id2name_map[product_id]; id2productid_map[brep_id] = product_id; if (Verbose()) { if (!pname.empty()) { std::cerr << std::endl << " Generating Product -" << pname ; } else { std::cerr << std::endl << " Generating Product"; } } LocalUnits::length = aBrep->GetLengthConversionFactor(); LocalUnits::planeangle = aBrep->GetPlaneAngleConversionFactor(); LocalUnits::solidangle = aBrep->GetSolidAngleConversionFactor(); ON_Brep *onBrep = aBrep->GetONBrep(); if (!onBrep) { bu_exit(1, "ERROR: failure creating advanced boundary representation from %s\n", stepfile.c_str()); } else { ON_TextLog tl; if (!onBrep->IsValid(&tl)) { bu_log("WARNING: %s is not valid\n", name.c_str()); } //onBrep->SpSplitClosedFaces(); //ON_Brep *tbrep = TightenBrep(onBrep); mat_t mat; MAT_IDN(mat); Axis2Placement3D *axis = aBrep->GetAxis2Placement3d(); if (axis != NULL) { //assign matrix values double translate_to[3]; const double *toXaxis = axis->GetXAxis(); const double *toYaxis = axis->GetYAxis(); const double *toZaxis = axis->GetZAxis(); mat_t rot_mat; VMOVE(translate_to,axis->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); MAT_IDN(rot_mat); VMOVE(&rot_mat[0], toXaxis); VMOVE(&rot_mat[4], toYaxis); VMOVE(&rot_mat[8], toZaxis); bn_mat_inv(mat, rot_mat); MAT_DELTAS_VEC(mat, translate_to); } dotg->WriteBrep(pname, onBrep,mat); delete onBrep; } } } } Factory::DeleteObjects(); } } } if (Verbose()) { std::cerr << std::endl << " Generating BRL-CAD hierarchy." << std::endl; } for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_context_dependent_shape_representation))) { ContextDependentShapeRepresentation *aCDSR = dynamic_cast<ContextDependentShapeRepresentation *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (aCDSR) { int rep_1_id = aCDSR->GetRepresentationRelationshipRep_1()->GetId(); int rep_2_id = aCDSR->GetRepresentationRelationshipRep_2()->GetId(); int pid_1 = id2productid_map[rep_1_id]; int pid_2 = id2productid_map[rep_2_id]; Axis2Placement3D *axis1 = NULL; Axis2Placement3D *axis2 = NULL; if ((id2name_map.find(rep_1_id) != id2name_map.end()) && (id2name_map.find(rep_2_id) != id2name_map.end())) { string comb = id2name_map[rep_1_id]; string member = id2name_map[rep_2_id]; mat_t mat; MAT_IDN(mat); ProductDefinition *relatingProduct = aCDSR->GetRelatingProductDefinition(); ProductDefinition *relatedProduct = aCDSR->GetRelatedProductDefinition(); if (relatingProduct && relatedProduct) { string relatingName = relatingProduct->GetProductName(); int relatingID = relatingProduct->GetProductId(); string relatedName = relatedProduct->GetProductName(); int relatedID = relatedProduct->GetProductId(); if ((relatingID == pid_1) && (relatedID == pid_2)) { axis1 = aCDSR->GetTransformItem_1(); axis2 = aCDSR->GetTransformItem_2(); comb = id2name_map[rep_1_id]; member = id2name_map[rep_2_id]; } else if ((relatingID == pid_2) && (relatedID == pid_1)) { axis1 = aCDSR->GetTransformItem_2(); axis2 = aCDSR->GetTransformItem_1(); comb = id2name_map[rep_2_id]; member = id2name_map[rep_1_id]; } else { std::cerr << "Error: Found Representation Relationship Rep_1(name=" << comb << ",Id=" << rep_1_id << ")" << std::endl; std::cerr << "Error: Found Representation Relationship Rep_2(name=" << member << ",Id=" << rep_2_id << ")" << std::endl; std::cerr << "Error: but Relating ProductDefinition (name=" << relatingName << ",Id=" << relatingID << ")" << std::endl; std::cerr << "Error: Related ProductDefinition (name=" << relatedName << ",Id=" << relatedID << ")" << std::endl; } } if ((axis1 != NULL) && (axis2 != NULL)) { mat_t to_mat; mat_t from_mat; mat_t toinv_mat; //assign matrix values double translate_to[3]; double translate_from[3]; const double *toXaxis = axis1->GetXAxis(); const double *toYaxis = axis1->GetYAxis(); const double *toZaxis = axis1->GetZAxis(); const double *fromXaxis = axis2->GetXAxis(); const double *fromYaxis = axis2->GetYAxis(); const double *fromZaxis = axis2->GetZAxis(); VMOVE(translate_to,axis1->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); VMOVE(translate_from,axis2->GetOrigin()); VSCALE(translate_from,translate_from,-LocalUnits::length); // undo from trans/rot MAT_IDN(from_mat); VMOVE(&from_mat[0], fromXaxis); VMOVE(&from_mat[4], fromYaxis); VMOVE(&from_mat[8], fromZaxis); MAT_DELTAS_VEC(from_mat, translate_from); // do to trans/rot MAT_IDN(to_mat); VMOVE(&to_mat[0], toXaxis); VMOVE(&to_mat[4], toYaxis); VMOVE(&to_mat[8], toZaxis); bn_mat_inv(toinv_mat, to_mat); MAT_DELTAS_VEC(toinv_mat, translate_to); bn_mat_mul(mat, toinv_mat, from_mat); } dotg->AddMember(comb,member,mat); } Factory::DeleteObjects(); } } } if (!dotg->WriteCombs()) { std::cerr << "Error writing BRL-CAD hierarchy." << std::endl; } return true; }
static void log_Run(void) { time_t clock_time; mat_t model2hv; /* model to h, v matrix */ mat_t hv2model; /* h, v tp model matrix */ quat_t orient; /* orientation */ point_t hv_eye; /* eye position in h, v coords */ point_t m_eye; /* eye position in model coords */ fastf_t hv_viewsize; /* size of view in h, v coords */ fastf_t m_viewsize; /* size of view in model coords. */ /* Current date and time get printed in header comment */ (void) time(&clock_time); (void) printf("# Log information produced by cell-fb %s\n", ctime(&clock_time)); (void) printf("az_el: %f %f\n", az, el); (void) printf("view_extrema: %f %f %f %f\n", SCRX2H(0), SCRX2H(fb_width), SCRY2V(0), SCRY2V(fb_height)); (void) printf("fb_size: %d %d\n", fb_width, fb_height); /* Produce the orientation, the model eye_pos, and the model * view size for input into rtregis. * First use the azimuth and elevation to produce the model2hv * matrix and use that to find the orientation. */ MAT_IDN(model2hv); MAT_IDN(hv2model); /* Print out the "view" just to keep rtregis from belly-aching */ printf("View: %g azimuth, %g elevation\n", az, el); /** mat_ae(model2hv, az, el); **/ /* Formula from rt/do.c */ bn_mat_angles(model2hv, 270.0+el, 0.0, 270.0-az); model2hv[15] = 25.4; /* input is in inches */ bn_mat_inv(hv2model, model2hv); quat_mat2quat(orient, model2hv); printf("Orientation: %.6f, %.6f, %.6f, %.6f\n", V4ARGS(orient)); /* Now find the eye position in h, v space. Note that the eye * is located at the center of the image; in this case, the center * of the screen space, i.e., the framebuffer.) * Also find the hv_viewsize at this time. */ hv_viewsize = SCRX2H((double)fb_width) - SCRX2H(0.0); hv_eye[0] = SCRX2H((double)fb_width/2); hv_eye[1] = SCRY2V((double)fb_height/2); hv_eye[2] = hv_viewsize/2; /* Debugging */ printf("hv_viewsize= %g\n", hv_viewsize); printf("hv_eye= %.6f, %.6f, %.6f\n", V3ARGS(hv_eye)); /* Now find the model eye_position and report on that */ MAT4X3PNT(m_eye, hv2model, hv_eye); printf("Eye_pos: %.6f, %.6f, %.6f\n", V3ARGS(m_eye)); /* * Find the view size in model coordinates and print that as well. * Important: Don't use %g format, it may round to nearest integer! */ m_viewsize = hv_viewsize/hv2model[15]; printf("Size: %.6f\n", m_viewsize); }
int ged_otranslate(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct _ged_trace_data gtd; struct rt_db_internal intern; vect_t delta; double scan[3]; mat_t dmat; mat_t emat; mat_t tmpMat; mat_t invXform; point_t rpp_min; point_t rpp_max; static const char *usage = "obj dx dy dz"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 5) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (_ged_get_obj_bounds2(gedp, 1, argv+1, >d, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; dp = gtd.gtd_obj[gtd.gtd_objpos-1]; if (!(dp->d_flags & RT_DIR_SOLID)) { if (_ged_get_obj_bounds(gedp, 1, argv+1, 1, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; } if (sscanf(argv[2], "%lf", &scan[X]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad x value - %s", argv[0], argv[2]); return GED_ERROR; } if (sscanf(argv[3], "%lf", &scan[Y]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad y value - %s", argv[0], argv[3]); return GED_ERROR; } if (sscanf(argv[4], "%lf", &scan[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad z value - %s", argv[0], argv[4]); return GED_ERROR; } MAT_IDN(dmat); VSCALE(delta, scan, gedp->ged_wdbp->dbip->dbi_local2base); MAT_DELTAS_VEC(dmat, delta); bn_mat_inv(invXform, gtd.gtd_xform); bn_mat_mul(tmpMat, invXform, dmat); bn_mat_mul(emat, tmpMat, gtd.gtd_xform); GED_DB_GET_INTERNAL(gedp, &intern, dp, emat, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; }
HIDDEN int scloud_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip) /* pointer to reg_udata in *rp */ { register struct scloud_specific *scloud; struct db_full_path full_path; mat_t region_to_model; mat_t model_to_region; mat_t tmp; BU_CK_VLS(matparm); BU_GET(scloud, struct scloud_specific); *dpp = scloud; if (rp->reg_aircode == 0) { bu_log("WARNING(%s): air shader '%s' applied to non-air region.\n%s\n", rp->reg_name, mfp->mf_name, " Set air flag with \"edcodes\" in mged"); bu_bomb(""); } memcpy(scloud, &scloud_defaults, sizeof(struct scloud_specific)); if (rdebug&RDEBUG_SHADE) bu_log("scloud_setup\n"); if (bu_struct_parse(matparm, scloud_parse, (char *)scloud) < 0) return -1; if (rdebug&RDEBUG_SHADE) (void)bu_struct_print(rp->reg_name, scloud_parse, (char *)scloud); /* get transformation between world and "region" coordinates */ if (db_string_to_path(&full_path, rtip->rti_dbip, rp->reg_name)) { /* bad thing */ bu_bomb("db_string_to_path() error"); } if (! db_path_to_mat(rtip->rti_dbip, &full_path, region_to_model, 0, &rt_uniresource)) { /* bad thing */ bu_bomb("db_path_to_mat() error"); } /* get matrix to map points from model space to "region" space */ bn_mat_inv(model_to_region, region_to_model); /* add the noise-space scaling */ MAT_IDN(tmp); if (!EQUAL(scloud->scale, 1.0)) { tmp[0] = tmp[5] = tmp[10] = 1.0 / scloud->scale; } else { tmp[0] = 1.0 / (scloud->vscale[0]); tmp[5] = 1.0 / (scloud->vscale[1]); tmp[10] = 1.0 / (scloud->vscale[2]); } bn_mat_mul(scloud->mtos, tmp, model_to_region); /* add the translation within noise space */ MAT_IDN(tmp); tmp[MDX] = scloud->delta[0]; tmp[MDY] = scloud->delta[1]; tmp[MDZ] = scloud->delta[2]; bn_mat_mul2(tmp, scloud->mtos); bn_mat_inv(scloud->stom, scloud->mtos); return 1; }
int ged_orotate(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct _ged_trace_data gtd; struct rt_db_internal intern; /* intentionally double for scan */ double xrot, yrot, zrot; mat_t rmat; mat_t pmat; mat_t emat; mat_t tmpMat; mat_t invXform; point_t rpp_min; point_t rpp_max; point_t keypoint; static const char *usage = "obj rX rY rZ [kX kY kZ]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 5 && argc != 8) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (sscanf(argv[2], "%lf", &xrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rX value - %s", argv[0], argv[2]); return GED_ERROR; } if (sscanf(argv[3], "%lf", &yrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rY value - %s", argv[0], argv[3]); return GED_ERROR; } if (sscanf(argv[4], "%lf", &zrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rZ value - %s", argv[0], argv[4]); return GED_ERROR; } if (argc == 5) { /* Use the object's center as the keypoint. */ if (_ged_get_obj_bounds2(gedp, 1, argv+1, >d, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; dp = gtd.gtd_obj[gtd.gtd_objpos-1]; if (!(dp->d_flags & RT_DIR_SOLID)) { if (_ged_get_obj_bounds(gedp, 1, argv+1, 1, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; } VADD2(keypoint, rpp_min, rpp_max); VSCALE(keypoint, keypoint, 0.5); } else { double scan[3]; /* The user has provided the keypoint. */ MAT_IDN(gtd.gtd_xform); if (sscanf(argv[5], "%lf", &scan[X]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kX value - %s", argv[0], argv[5]); return GED_ERROR; } if (sscanf(argv[6], "%lf", &scan[Y]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kY value - %s", argv[0], argv[6]); return GED_ERROR; } if (sscanf(argv[7], "%lf", &scan[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kZ value - %s", argv[0], argv[7]); return GED_ERROR; } VSCALE(keypoint, scan, gedp->ged_wdbp->dbip->dbi_local2base); if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_QUIET)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: %s not found", argv[0], argv[1]); return GED_ERROR; } } bn_mat_angles(rmat, xrot, yrot, zrot); bn_mat_xform_about_pt(pmat, rmat, keypoint); bn_mat_inv(invXform, gtd.gtd_xform); bn_mat_mul(tmpMat, invXform, pmat); bn_mat_mul(emat, tmpMat, gtd.gtd_xform); GED_DB_GET_INTERNAL(gedp, &intern, dp, emat, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; }
/** * In theory, the grid can be specified by providing any two of * these sets of parameters: * * number of pixels (width, height) * viewsize (in model units, mm) * number of grid cells (cell_width, cell_height) * * however, for now, it is required that the view size always be * specified, and one or the other parameter be provided. */ void grid_setup(void) { vect_t temp; mat_t toEye; if (viewsize <= 0.0) bu_exit(EXIT_FAILURE, "viewsize <= 0"); /* model2view takes us to eye_model location & orientation */ MAT_IDN(toEye); MAT_DELTAS_VEC_NEG(toEye, eye_model); Viewrotscale[15] = 0.5*viewsize; /* Viewscale */ bn_mat_mul(model2view, Viewrotscale, toEye); bn_mat_inv(view2model, model2view); /* Determine grid cell size and number of pixels */ if (cell_newsize) { if (cell_width <= 0.0) cell_width = cell_height; if (cell_height <= 0.0) cell_height = cell_width; width = (viewsize / cell_width) + 0.99; height = (viewsize / (cell_height*aspect)) + 0.99; cell_newsize = 0; } else { /* Chop -1.0..+1.0 range into parts */ cell_width = viewsize / width; cell_height = viewsize / (height*aspect); } /* * Optional GIFT compatibility, mostly for RTG3. Round coordinates * of lower left corner to fall on integer- valued coordinates, in * "gift_grid_rounding" units. */ if (gift_grid_rounding > 0.0) { point_t v_ll; /* view, lower left */ point_t m_ll; /* model, lower left */ point_t hv_ll; /* hv, lower left*/ point_t hv_wanted; vect_t hv_delta; vect_t m_delta; mat_t model2hv; mat_t hv2model; /* Build model2hv matrix, including mm2inches conversion */ MAT_COPY(model2hv, Viewrotscale); model2hv[15] = gift_grid_rounding; bn_mat_inv(hv2model, model2hv); VSET(v_ll, -1, -1, 0); MAT4X3PNT(m_ll, view2model, v_ll); MAT4X3PNT(hv_ll, model2hv, m_ll); VSET(hv_wanted, floor(hv_ll[X]), floor(hv_ll[Y]), floor(hv_ll[Z])); VSUB2(hv_delta, hv_ll, hv_wanted); MAT4X3PNT(m_delta, hv2model, hv_delta); VSUB2(eye_model, eye_model, m_delta); MAT_DELTAS_VEC_NEG(toEye, eye_model); bn_mat_mul(model2view, Viewrotscale, toEye); bn_mat_inv(view2model, model2view); } /* Create basis vectors dx and dy for emanation plane (grid) */ VSET(temp, 1, 0, 0); MAT3X3VEC(dx_unit, view2model, temp); /* rotate only */ VSCALE(dx_model, dx_unit, cell_width); VSET(temp, 0, 1, 0); MAT3X3VEC(dy_unit, view2model, temp); /* rotate only */ VSCALE(dy_model, dy_unit, cell_height); if (stereo) { /* Move left 2.5 inches (63.5mm) */ VSET(temp, -63.5*2.0/viewsize, 0, 0); bu_log("red eye: moving %f relative screen (left)\n", temp[X]); MAT4X3VEC(left_eye_delta, view2model, temp); VPRINT("left_eye_delta", left_eye_delta); } /* "Lower left" corner of viewing plane */ if (rt_perspective > 0.0) { fastf_t zoomout; zoomout = 1.0 / tan(DEG2RAD * rt_perspective / 2.0); VSET(temp, -1, -1/aspect, -zoomout); /* viewing plane */ /* * divergence is perspective angle divided by the number of * pixels in that angle. Extra factor of 0.5 is because * perspective is a full angle while divergence is the tangent * (slope) of a half angle. */ APP.a_diverge = tan(DEG2RAD * rt_perspective * 0.5 / width); APP.a_rbeam = 0; } else { /* all rays go this direction */ VSET(temp, 0, 0, -1); MAT4X3VEC(APP.a_ray.r_dir, view2model, temp); VUNITIZE(APP.a_ray.r_dir); VSET(temp, -1, -1/aspect, 0); /* eye plane */ APP.a_rbeam = 0.5 * viewsize / width; APP.a_diverge = 0; } if (ZERO(APP.a_rbeam) && ZERO(APP.a_diverge)) bu_exit(EXIT_FAILURE, "zero-radius beam"); MAT4X3PNT(viewbase_model, view2model, temp); if (jitter & JITTER_FRAME) { /* Move the frame in a smooth circular rotation in the plane */ fastf_t ang; /* radians */ fastf_t dx, dy; ang = curframe * frame_delta_t * M_2PI / 10; /* 10 sec period */ dx = cos(ang) * 0.5; /* +/- 1/4 pixel width in amplitude */ dy = sin(ang) * 0.5; VJOIN2(viewbase_model, viewbase_model, dx, dx_model, dy, dy_model); } if (cell_width <= 0 || cell_width >= INFINITY || cell_height <= 0 || cell_height >= INFINITY) { bu_log("grid_setup: cell size ERROR (%g, %g) mm\n", cell_width, cell_height); bu_exit(EXIT_FAILURE, "cell size"); } if (width <= 0 || height <= 0) { bu_log("grid_setup: ERROR bad image size (%zu, %zu)\n", width, height); bu_exit(EXIT_FAILURE, "bad size"); } }
int _ged_do_rot(struct ged *gedp, char coord, mat_t rmat, int (*func)()) { mat_t temp1, temp2; if (func != (int (*)())0) return (*func)(gedp, coord, gedp->ged_gvp->gv_rotate_about, rmat); switch (coord) { case 'm': /* transform model rotations into view rotations */ bn_mat_inv(temp1, gedp->ged_gvp->gv_rotation); bn_mat_mul(temp2, gedp->ged_gvp->gv_rotation, rmat); bn_mat_mul(rmat, temp2, temp1); break; case 'v': default: break; } /* Calculate new view center */ if (gedp->ged_gvp->gv_rotate_about != 'v') { point_t rot_pt; point_t new_origin; mat_t viewchg, viewchginv; point_t new_cent_view; point_t new_cent_model; switch (gedp->ged_gvp->gv_rotate_about) { case 'e': VSET(rot_pt, 0.0, 0.0, 1.0); break; case 'k': MAT4X3PNT(rot_pt, gedp->ged_gvp->gv_model2view, gedp->ged_gvp->gv_keypoint); break; case 'm': /* rotate around model center (0, 0, 0) */ VSET(new_origin, 0.0, 0.0, 0.0); MAT4X3PNT(rot_pt, gedp->ged_gvp->gv_model2view, new_origin); break; default: return GED_ERROR; } bn_mat_xform_about_pt(viewchg, rmat, rot_pt); bn_mat_inv(viewchginv, viewchg); /* Convert origin in new (viewchg) coords back to old view coords */ VSET(new_origin, 0.0, 0.0, 0.0); MAT4X3PNT(new_cent_view, viewchginv, new_origin); MAT4X3PNT(new_cent_model, gedp->ged_gvp->gv_view2model, new_cent_view); MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, new_cent_model); } /* pure rotation */ bn_mat_mul2(rmat, gedp->ged_gvp->gv_rotation); ged_view_update(gedp->ged_gvp); return GED_OK; }
static void tree_solids(union tree *tp, struct tree_bark *tb, int op, struct resource *resp) { RT_CK_TREE(tp); switch (tp->tr_op) { case OP_NOP: return; case OP_SOLID: { struct reg_db_internals *dbint; matp_t mp; long sol_id = 0; struct rt_ell_internal *ell_p; vect_t v; int ret; BU_ALLOC(dbint, struct reg_db_internals); BU_LIST_INIT_MAGIC(&(dbint->l), DBINT_MAGIC); if (tp->tr_a.tu_stp->st_matp) mp = tp->tr_a.tu_stp->st_matp; else mp = (matp_t)bn_mat_identity; /* Get the internal form of this solid & add it to the list */ ret = rt_db_get_internal(&dbint->ip, tp->tr_a.tu_stp->st_dp, tb->dbip, mp, resp); if (ret < 0) { bu_log("Failure reading %s object from database.\n", OBJ[sol_id].ft_name); return; } RT_CK_DB_INTERNAL(&dbint->ip); dbint->st_p = tp->tr_a.tu_stp; sol_id = dbint->ip.idb_type; if (sol_id < 0) { bu_log("Primitive ID %ld out of bounds\n", sol_id); bu_bomb(""); } if (sol_id != ID_ELL) { if (op == OP_UNION) bu_log("Non-ellipse \"union\" primitive of \"%s\" being ignored\n", tb->name); if (rdebug&RDEBUG_SHADE) bu_log(" got a primitive type %ld \"%s\". This primitive ain't no ellipse bucko!\n", sol_id, OBJ[sol_id].ft_name); break; } ell_p = (struct rt_ell_internal *)dbint->ip.idb_ptr; if (rdebug&RDEBUG_SHADE) bu_log(" got a primitive type %ld \"%s\"\n", sol_id, OBJ[sol_id].ft_name); RT_ELL_CK_MAGIC(ell_p); if (rdebug&RDEBUG_SHADE) { VPRINT("point", ell_p->v); VPRINT("a", ell_p->a); VPRINT("b", ell_p->b); VPRINT("c", ell_p->c); } /* create the matrix that maps the coordinate system defined * by the ellipse into model space, and get inverse for use * in the _render() proc */ MAT_IDN(mp); VMOVE(v, ell_p->a); VUNITIZE(v); mp[0] = v[0]; mp[4] = v[1]; mp[8] = v[2]; VMOVE(v, ell_p->b); VUNITIZE(v); mp[1] = v[0]; mp[5] = v[1]; mp[9] = v[2]; VMOVE(v, ell_p->c); VUNITIZE(v); mp[2] = v[0]; mp[6] = v[1]; mp[10] = v[2]; MAT_DELTAS_VEC(mp, ell_p->v); MAT_COPY(dbint->ell2model, mp); bn_mat_inv(dbint->model2ell, mp); /* find scaling of gaussian puff in ellipsoid space */ VSET(dbint->one_sigma, MAGNITUDE(ell_p->a) / tb->gs->gauss_sigma, MAGNITUDE(ell_p->b) / tb->gs->gauss_sigma, MAGNITUDE(ell_p->c) / tb->gs->gauss_sigma); if (rdebug&RDEBUG_SHADE) { VPRINT("sigma", dbint->one_sigma); } BU_LIST_APPEND(tb->l, &(dbint->l)); break; } case OP_UNION: tree_solids(tp->tr_b.tb_left, tb, tp->tr_op, resp); tree_solids(tp->tr_b.tb_right, tb, tp->tr_op, resp); break; case OP_NOT: bu_log("Warning: 'Not' region operator in %s\n", tb->name); tree_solids(tp->tr_b.tb_left, tb, tp->tr_op, resp); break; case OP_GUARD:bu_log("Warning: 'Guard' region operator in %s\n", tb->name); tree_solids(tp->tr_b.tb_left, tb, tp->tr_op, resp); break; case OP_XNOP:bu_log("Warning: 'XNOP' region operator in %s\n", tb->name); tree_solids(tp->tr_b.tb_left, tb, tp->tr_op, resp); break; case OP_INTERSECT: case OP_SUBTRACT: case OP_XOR: /* XXX this can get us in trouble if 1 solid is subtracted * from less than all the "union" solids of the region. */ tree_solids(tp->tr_b.tb_left, tb, tp->tr_op, resp); tree_solids(tp->tr_b.tb_right, tb, tp->tr_op, resp); return; default: bu_bomb("rt_tree_region_assign: bad op\n"); } }
/* * * M A I N * * Main exists to coordinate the actions of the parts of this program. * It also processes its own arguments (argc and argv). */ int main(int argc, char **argv) { mat_t mod2view1; /* first log matrix its view */ mat_t mod2view2; /* second log matrix to its view*/ mat_t regismat; /* registration matrix */ mat_t view2model; /* matrix for converting from view to model space */ int ret; /* function return code */ MAT_IDN(mod2view1); /* makes an identity matrix */ MAT_IDN(mod2view2); MAT_IDN(regismat); /* Check to see that the correct format is given, else print * usage message. */ if (argc != 3) { fputs(usage, stderr); return 1; } /* Now process the arguments from main: i.e. open the log files * for reading and send to read_rt_file(). * Send read_rt_file() a pointer to local model matrix * and to the appropriate log file. * ( Note &view2model[0] can be used, but is not elegant.) */ fp = fopen(argv[1], "r"); if ( fp == NULL ) { perror(argv[1]); return 1; } ret = read_rt_file(fp, argv[1], mod2view1); if (ret < 0) { return 2; } fclose(fp); /* clean up */ fp = fopen(argv[2], "r"); if ( fp == NULL ) { perror(argv[2]); return 2; } ret = read_rt_file(fp, argv[2], mod2view2); if (ret < 0) { return 2; } fclose(fp); if (verbose) { bn_mat_inv(view2model, mod2view1); bn_mat_print("mod2view1-plot.log", mod2view1); bn_mat_print("mod2view2-pix.log", mod2view2); fprintf(stderr, "mod2view1[0, 1, 2, 3, 15]: %.6f, %.6f, %.6f, %.6f, %.6f\n", mod2view1[0], mod2view1[1], mod2view1[2], mod2view1[3], mod2view1[15]); } /* Now build the registration matrix for the two files. */ ret = mat_build(mod2view1, mod2view2, regismat); if (ret == FALSE) { fprintf(stderr, "regis: can't build registration matrix!\n"); return 3; } print_info(regismat); return 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"); }
int ged_move_botpts(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "bot vec vertex_1 [vertex_2 ... vertex_n]"; struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *botip; mat_t mat; register int i; size_t vertex_i; char *last; /* must be double for scanf */ double vec[ELEMENTS_PER_VECT]; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if ((last = strrchr(argv[1], '/')) == NULL) last = (char *)argv[1]; else ++last; if (last[0] == '\0') { bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]); return GED_ERROR; } dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (bu_sscanf(argv[2], "%lf %lf %lf", &vec[X], &vec[Y], &vec[Z]) != 3) { bu_vls_printf(gedp->ged_result_str, "%s: bad vector - %s", argv[0], argv[2]); return GED_ERROR; } VSCALE(vec, vec, gedp->ged_wdbp->dbip->dbi_local2base); if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { bu_vls_printf(gedp->ged_result_str, "Object is not a BOT"); rt_db_free_internal(&intern); return GED_ERROR; } botip = (struct rt_bot_internal *)intern.idb_ptr; for (i = 3; i < argc; ++i) { if (bu_sscanf(argv[i], "%zu", &vertex_i) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]); continue; } if (vertex_i >= botip->num_vertices) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]); continue; } VADD2(&botip->vertices[vertex_i*3], vec, &botip->vertices[vertex_i*3]); } { mat_t invmat; point_t curr_pt; size_t idx; bn_mat_inv(invmat, mat); for (idx = 0; idx < botip->num_vertices; idx++) { MAT4X3PNT(curr_pt, invmat, &botip->vertices[idx*3]); VMOVE(&botip->vertices[idx*3], curr_pt); } } GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); rt_db_free_internal(&intern); return GED_OK; }
/** * R T _ G E T T R E E _ R E G I O N _ E N D * * This routine will be called by db_walk_tree() once all the solids * in this region have been visited. * * This routine must be prepared to run in parallel. As a result, * note that the details of the solids pointed to by the soltab * pointers in the tree may not be filled in when this routine is * called (due to the way multiple instances of solids are handled). * Therefore, everything which referred to the tree has been moved out * into the serial section. (rt_tree_region_assign, rt_bound_tree) */ HIDDEN union tree *rt_gettree_region_end(register struct db_tree_state *tsp, struct db_full_path *pathp, union tree *curtree, genptr_t client_data) { struct region *rp; struct directory *dp; int shader_len=0; struct rt_i *rtip; int i; Tcl_HashTable *tbl = (Tcl_HashTable *)client_data; Tcl_HashEntry *entry; matp_t inv_mat; RT_CK_DBI(tsp->ts_dbip); RT_CK_FULL_PATH(pathp); RT_CK_TREE(curtree); rtip = tsp->ts_rtip; RT_CK_RTI(rtip); RT_CK_RESOURCE(tsp->ts_resp); if ( curtree->tr_op == OP_NOP ) { /* Ignore empty regions */ return curtree; } BU_GETSTRUCT( rp, region ); rp->l.magic = RT_REGION_MAGIC; rp->reg_regionid = tsp->ts_regionid; rp->reg_is_fastgen = tsp->ts_is_fastgen; rp->reg_aircode = tsp->ts_aircode; rp->reg_gmater = tsp->ts_gmater; rp->reg_los = tsp->ts_los; if ( tsp->ts_attrs.count && tsp->ts_attrs.avp ) { rp->attr_values = (struct bu_mro **)bu_calloc( tsp->ts_attrs.count+1, sizeof( struct bu_mro *), "regp->attr_values" ); for ( i=0; i<tsp->ts_attrs.count; i++ ) { rp->attr_values[i] = bu_malloc( sizeof( struct bu_mro ), "rp->attr_values[i]" ); bu_mro_init_with_string( rp->attr_values[i], tsp->ts_attrs.avp[i].value ); } } else { rp->attr_values = (struct bu_mro **)NULL; } rp->reg_mater = tsp->ts_mater; /* struct copy */ if ( tsp->ts_mater.ma_shader ) shader_len = strlen( tsp->ts_mater.ma_shader ); if ( shader_len ) { rp->reg_mater.ma_shader = bu_strdup( tsp->ts_mater.ma_shader ); } else rp->reg_mater.ma_shader = (char *)NULL; rp->reg_name = db_path_to_string( pathp ); dp = (struct directory *)DB_FULL_PATH_CUR_DIR(pathp); if (RT_G_DEBUG&DEBUG_TREEWALK) { bu_log("rt_gettree_region_end() %s\n", rp->reg_name ); rt_pr_tree( curtree, 0 ); } rp->reg_treetop = curtree; rp->reg_all_unions = db_is_tree_all_unions( curtree ); /* Determine material properties */ rp->reg_mfuncs = (char *)0; rp->reg_udata = (char *)0; if ( rp->reg_mater.ma_color_valid == 0 ) rt_region_color_map(rp); /* enter critical section */ bu_semaphore_acquire( RT_SEM_RESULTS ); rp->reg_instnum = dp->d_uses++; /* * Add the region to the linked list of regions. * Positions in the region bit vector are established at this time. */ BU_LIST_INSERT( &(rtip->HeadRegion), &rp->l ); /* Assign bit vector pos. */ rp->reg_bit = rtip->nregions++; /* leave critical section */ bu_semaphore_release( RT_SEM_RESULTS ); if ( tbl && bu_avs_get( &tsp->ts_attrs, "ORCA_Comp" ) ) { int newentry; long int reg_bit = rp->reg_bit; inv_mat = (matp_t)bu_calloc( 16, sizeof( fastf_t ), "inv_mat" ); if ( tsp->ts_mat ) bn_mat_inv( inv_mat, tsp->ts_mat ); else MAT_IDN( inv_mat ); /* enter critical section */ bu_semaphore_acquire( RT_SEM_RESULTS ); entry = Tcl_CreateHashEntry(tbl, (char *)reg_bit, &newentry); Tcl_SetHashValue( entry, (ClientData)inv_mat ); /* leave critical section */ bu_semaphore_release( RT_SEM_RESULTS ); } if ( RT_G_DEBUG & DEBUG_REGIONS ) { bu_log("Add Region %s instnum %d\n", rp->reg_name, rp->reg_instnum); } /* Indicate that we have swiped 'curtree' */ return(TREE_NULL); }