void MSceneMessage_AfterImportOpen_CallbackFunc(void *callbackData) { MStatus status; MItDag it(MItDag::kBreadthFirst, MFn::kTransform, &status); if (!status) { status.perror("MItDag::#ctor"); return; } for(; !it.isDone(); it.next()) { MObject object = it.item(&status); if (!status) { status.perror("MObject::item"); return; } /* * Make sure the object is a Helix */ MFnDagNode dagNode(object); if (dagNode.typeId(&status) == ::Helix::Helix::id) { /* * This object is a helix, iterate over all of its bases and set their translation */ Model::Helix helix(object); for(Model::Helix::BaseIterator it = helix.begin(); it != helix.end(); ++it) { MFnTransform base_transform(it->getDagPath(status)); if (!status) { status.perror("MFnTransform::getDagPath"); return; } MVector translation = base_transform.getTranslation(MSpace::kTransform, &status); if (!status) { status.perror("MFnTransform::getTranslation"); return; } if (!(status = base_transform.setTranslation(translation, MSpace::kTransform))) { status.perror("MFnTransform::setTranslation"); return; } } } } }
void simulated_annealing(scene & mesh, physics & phys, int kmax, float emax, unsigned int minbasecount, int baserange, StoreBestFunctorT store_best_functor, RunningFunctorT running_functor) { int modifiedHelix, previousBaseCount; physics::transform_type previousTransform; scene::HelixContainer & helices(mesh.getHelices()); const scene::HelixContainer::size_type helixCount(helices.size()); simulated_annealing(mesh, [](scene & mesh) { return mesh.getTotalSeparation(); }, [&helixCount](float k) { return float(std::max(0., (exp(-k) - 1 / M_E) / (1 - 1 / M_E))) * helixCount; }, [&modifiedHelix, &helices, &helixCount, &previousBaseCount, &previousTransform, &phys, &minbasecount, &baserange, &running_functor](scene & mesh) { for (Helix & helix : helices) helix.setTransform(helix.getInitialTransform()); modifiedHelix = rand() % helixCount; Helix & helix(helices[modifiedHelix]); previousBaseCount = helix.getBaseCount(); previousTransform = helix.getTransform(); helix.recreateRigidBody( phys, std::max(minbasecount, helix.getInitialBaseCount() + (rand() % 2 * 2 - 1) * (1 + rand() % (baserange))), helix.getInitialTransform()); while (!mesh.isSleeping() && running_functor()) { phys.scene->simulate(1.0f / 60.0f); phys.scene->fetchResults(true); } }, probability_functor<float, float>(), [&modifiedHelix, &helices, &previousBaseCount, &previousTransform, &phys](scene & mesh) { Helix & helix(helices[modifiedHelix]); helix.recreateRigidBody(phys, previousBaseCount, helix.getInitialTransform()); }, store_best_functor, running_functor, kmax, emax); }
/* random_helix_or_trig */ static unsigned long helix_draw (Display *dpy, Window window, void *closure) { struct state *st = (struct state *) closure; Bool free_color = False; XColor color; int delay = st->subdelay; int erase_delay = 10000; int ii; if (st->eraser) { st->eraser = erase_window (dpy, window, st->eraser); if (st->eraser) delay = erase_delay; goto END; } switch (st->dstate) { case LINGER: delay = st->sleep_time * 1000000; st->dstate = ERASE; break; case ERASE: st->eraser = erase_window (dpy, window, st->eraser); delay = erase_delay; if (free_color) XFreeColors (dpy, st->cmap, &color.pixel, 1, 0); st->dstate = (random() & 1) ? HELIX : TRIG; break; case DRAW_HELIX: for (ii = 0; ii < 10; ii++) { helix (dpy, window, st); if (st->dstate != DRAW_HELIX) break; } break; case DRAW_TRIG: for (ii = 0; ii < 5; ii++) { trig (dpy, window, st); if (st->dstate != DRAW_TRIG) break; } break; case HELIX: random_helix (dpy, window, st, &color, &free_color); st->dstate = DRAW_HELIX; break; case TRIG: random_trig(dpy, window, st, &color, &free_color); st->dstate = DRAW_TRIG; break; default: abort(); } END: return delay; }
/* datagn is the main routine for input of geometry data. */ gboolean datagn( void ) { char gm[3]; /* input card mnemonic list */ char *atst[] = { "GW", "GX", "GR", "GS", "GE","GM", "SP",\ "SM", "GA", "SC", "GH", "GF", "CT" }; int nwire, isct, itg, iy=0, iz; size_t mreq; int ix, i, ns, gm_num; /* geometry card id as a number */ double rad, xs1, xs2, ys1, ys2, zs1, zs2; double x3=0, y3=0, z3=0, x4=0, y4=0, z4=0; double xw1, xw2, yw1, yw2, zw1, zw2; double dummy; data.ipsym=0; nwire=0; data.n=0; data.np=0; data.m=0; data.mp=0; isct=0; structure_proj_params.r_max = 0.0; /* read geometry data card and branch to */ /* section for operation requested */ do { if( !readgm(gm, &itg, &ns, &xw1, &yw1, &zw1, &xw2, &yw2, &zw2, &rad) ) return( FALSE ); /* identify card id mnemonic */ for( gm_num = 0; gm_num < NUM_GEOMN; gm_num++ ) if( strncmp( gm, atst[gm_num], 2) == 0 ) break; if( gm_num != 9 ) isct=0; switch( gm_num ) { case GW: /* "gw" card, generate segment data for straight wire. */ if( Tag_Seg_Error(itg, ns) ) return( FALSE ); nwire++; if( rad != 0.0) { xs1=1.0; ys1=1.0; } else { if( !readgm(gm, &ix, &iy, &xs1, &ys1, &zs1, &dummy, &dummy, &dummy, &dummy) ) return( FALSE ); if( strcmp(gm, "GC" ) != 0 ) { fprintf( stderr, "xnec2c: datagn(): geometry data card error " "no GC card for tapered wire\n" ); stop( _("datagn(): Geometry data error\n"\ "No GC card for tapered wire"), ERR_OK ); return( FALSE ); } if( (ys1 == 0.0) || (zs1 == 0.0) ) { fprintf( stderr, "xnec2c: datagn(): geometry GC data card error\n" ); stop( _("datagn(): Geometry GC data card error"), ERR_OK ); return( FALSE ); } rad= ys1; ys1= pow( (zs1/ys1), (1.0/(ns-1.0)) ); } wire( xw1, yw1, zw1, xw2, yw2, zw2, rad, xs1, ys1, ns, itg); continue; /* reflect structure along x,y, or z */ /* axes or rotate to form cylinder. */ case GX: /* "gx" card */ if( (ns < 0) || (itg < 0) ) { fprintf( stderr, "xnec2c: datagn(): geometry GX data card error\n" ); stop( _("datagn(): Geometry GX data card error"), ERR_OK ); return( FALSE ); } iy= ns/10; iz= ns- iy*10; ix= iy/10; iy= iy- ix*10; if( ix != 0) ix=1; if( iy != 0) iy=1; if( iz != 0) iz=1; if( !reflc(ix, iy, iz, itg, ns) ) return( FALSE ); continue; case GR: /* "gr" card */ if( (ns < 0) || (itg < 0) ) { fprintf( stderr, "xnec2c: datagn(): geometry GR data card error\n" ); stop( _("datagn(): Geometry GR data card error"), ERR_OK ); return( FALSE ); } ix=-1; iz = 0; if( !reflc(ix, iy, iz, itg, ns) ) return( FALSE ); continue; case GS: /* "gs" card, scale structure dimensions by factor xw1 */ if( (itg > 0) && (ns > 0) && (ns >= itg) ) { for( i = 0; i < data.n; i++ ) { if( (data.itag[i] >= itg) && (data.itag[i] <= ns) ) { data.x1[i]= data.x1[i]* xw1; data.y1[i]= data.y1[i]* xw1; data.z1[i]= data.z1[i]* xw1; data.x2[i]= data.x2[i]* xw1; data.y2[i]= data.y2[i]* xw1; data.z2[i]= data.z2[i]* xw1; data.bi[i]= data.bi[i]* xw1; } } /* FIXME corrects errors when GS follows GX but this is just a work-around */ data.np = data.n; data.ipsym = 0; } else for( i = 0; i < data.n; i++ ) { data.x1[i]= data.x1[i]* xw1; data.y1[i]= data.y1[i]* xw1; data.z1[i]= data.z1[i]* xw1; data.x2[i]= data.x2[i]* xw1; data.y2[i]= data.y2[i]* xw1; data.z2[i]= data.z2[i]* xw1; data.bi[i]= data.bi[i]* xw1; } yw1= xw1* xw1; for( i = 0; i < data.m; i++ ) { data.px[i] = data.px[i]* xw1; data.py[i] = data.py[i]* xw1; data.pz[i] = data.pz[i]* xw1; data.pbi[i]= data.pbi[i]* yw1; } continue; case GE: /* "ge" card, terminate structure geometry input. */ /* My addition, for drawing */ if( ((data.n > 0) || (data.m > 0)) && !CHILD ) Init_Struct_Drawing(); else if( (data.n == 0) && (data.m == 0) ) { stop( _("No geometry data cards"), ERR_OK ); return( FALSE ); } if( !conect(itg) ) return( FALSE ); if( data.n != 0) { /* Allocate wire buffers */ mreq = (size_t)data.n * sizeof(double); mem_realloc( (void **)&data.si, mreq, "in input.c" ); mem_realloc( (void **)&data.sab, mreq, "in input.c" ); mem_realloc( (void **)&data.cab, mreq, "in input.c" ); mem_realloc( (void **)&data.salp, mreq, "in input.c" ); mem_realloc( (void **)&data.x, mreq, "in input.c" ); mem_realloc( (void **)&data.y, mreq, "in input.c" ); mem_realloc( (void **)&data.z, mreq, "in input.c" ); for( i = 0; i < data.n; i++ ) { xw1= data.x2[i]- data.x1[i]; yw1= data.y2[i]- data.y1[i]; zw1= data.z2[i]- data.z1[i]; data.x[i]=( data.x1[i]+ data.x2[i])/2.0; data.y[i]=( data.y1[i]+ data.y2[i])/2.0; data.z[i]=( data.z1[i]+ data.z2[i])/2.0; xw2= xw1* xw1+ yw1* yw1+ zw1* zw1; yw2= sqrt( xw2); //yw2=( xw2/yw2 + yw2)/2.0; data.si[i]= yw2; data.cab[i]= xw1/ yw2; data.sab[i]= yw1/ yw2; xw2= zw1/ yw2; if( xw2 > 1.0) xw2=1.0; if( xw2 < -1.0) xw2=-1.0; data.salp[i]= xw2; //xw2= asin( xw2)* TD; //yw2= atan2( yw1, xw1)* TD; if( (data.si[i] <= 1.0e-20) || (data.bi[i] <= 0.0) ) { fprintf( stderr, "xnec2c: datagn(): segment data error\n" ); stop( _("datagn(): Segment data error"), ERR_OK ); return( FALSE ); } } /* for( i = 0; i < data.n; i++ ) */ } /* if( data.n != 0) */ if( data.m != 0) { for( i = 0; i < data.m; i++ ) { xw1=( data.t1y[i]* data.t2z[i] - data.t1z[i]* data.t2y[i])* data.psalp[i]; yw1=( data.t1z[i]* data.t2x[i] - data.t1x[i]* data.t2z[i])* data.psalp[i]; zw1=( data.t1x[i]* data.t2y[i] - data.t1y[i]* data.t2x[i])* data.psalp[i]; } /* for( i = 0; i < data.m; i++ ) */ } /* if( data.m != 0) */ data.npm = data.n+data.m; data.np2m = data.n+2*data.m; data.np3m = data.n+3*data.m; return( TRUE ); /* "gm" card, move structure or reproduce */ /* original structure in new positions. */ case GM: { int tgf = (int)(rad + 0.5); if( (tgf < 0) || (ns < 0) || (rad < 0.0) ) { fprintf( stderr, "xnec2c: datagn(): move GM data card error\n" ); stop( _("datagn(): Move GM data card error"), ERR_OK ); return( FALSE ); } xw1= xw1* TA; yw1= yw1* TA; zw1= zw1* TA; if( !move(xw1, yw1, zw1, xw2, yw2, zw2, (int)(rad+.5), ns, itg) ) return( FALSE ); } continue; case SP: /* "sp" card, generate single new patch */ ns++; if( itg != 0) { fprintf( stderr, "xnec2c: datagn(): patch data card error\n" ); stop( _("datagn(): Patch data card error"), ERR_OK ); return( FALSE ); } if( (ns == 2) || (ns == 4) ) isct=1; if( ns > 1) { if( !readgm(gm, &ix, &iy, &x3, &y3, &z3, &x4, &y4, &z4, &dummy) ) return( FALSE ); if( (ns == 2) || (itg > 0) ) { x4= xw1+ x3- xw2; y4= yw1+ y3- yw2; z4= zw1+ z3- zw2; } if( strcmp(gm, "SC") != 0 ) { fprintf( stderr, "xnec2c: datagn(): patch data error\n" ); stop( _("datagn(): Patch data error"), ERR_OK ); return( FALSE ); } } /* if( ns > 1) */ else { xw2= xw2* TA; yw2= yw2* TA; } if( !patch( itg, ns, xw1, yw1, zw1, xw2, yw2, zw2, x3, y3, z3, x4, y4, z4) ) return( FALSE ); continue; case SM: /* "sm" card, generate multiple-patch surface */ if( (itg < 1) || (ns < 1) ) { fprintf( stderr, "datagn(): xnec2c: patch card data error\n" ); stop( _("datagn(): Patch data card error"), ERR_OK ); return( FALSE ); } if( !readgm(gm, &ix, &iy, &x3, &y3, &z3, &x4, &y4, &z4, &dummy) ) return( FALSE ); if( (ns == 2) || (itg > 0) ) { x4= xw1+ x3- xw2; y4= yw1+ y3- yw2; z4= zw1+ z3- zw2; } if( strcmp(gm, "SC" ) != 0 ) { fprintf( stderr, "xnec2c: datagn(): patch card data error\n" ); stop( _("datagn(): Patch data card error"), ERR_OK ); return( FALSE ); } if( !patch(itg, ns, xw1, yw1, zw1, xw2, yw2, zw2, x3, y3, z3, x4, y4, z4) ) return( FALSE ); continue; case GA: /* "ga" card, generate segment data for wire arc */ if( Tag_Seg_Error(itg, ns) ) return( FALSE ); nwire++; if( !arc(itg, ns, xw1, yw1, zw1, xw2) ) return( FALSE ); continue; case SC: /* "sc" card */ if( isct == 0) { fprintf( stderr, "xnec2c: datagn(): patch data card error\n" ); stop( _("datagn(): Patch data card error"), ERR_OK ); return( FALSE ); } ns++; if( (itg != 0) || ((ns != 2) && (ns != 4)) ) { fprintf( stderr, "xnec2c: datagn(): patch data card error\n" ); stop( _("datagn(): Patch data card error"), ERR_OK ); return( FALSE ); } xs1= x4; ys1= y4; zs1= z4; xs2= x3; ys2= y3; zs2= z3; x3= xw1; y3= yw1; z3= zw1; if( ns == 4) { x4= xw2; y4= yw2; z4= zw2; } xw1= xs1; yw1= ys1; zw1= zs1; xw2= xs2; yw2= ys2; zw2= zs2; if( ns != 4) { x4= xw1+ x3- xw2; y4= yw1+ y3- yw2; z4= zw1+ z3- zw2; } if( !patch(itg, ns, xw1, yw1, zw1, xw2, yw2, zw2, x3, y3, z3, x4, y4, z4) ) return( FALSE ); continue; case GH: /* "gh" card, generate helix */ if( Tag_Seg_Error(itg, ns) ) return( FALSE ); nwire++; helix( xw1, yw1, zw1, xw2, yw2, zw2, rad, ns, itg); continue; case GF: /* "gf" card, not supported */ fprintf( stderr, "xnec2c: datagn(): \"GF\" card (NGF solution) " "is not supported\n" ); stop( _("datagn(): \"GF\" card (NGF solution)\n"\ "is not supported"), ERR_OK ); return( FALSE ); case CT: /* Ignore in-data comments (NEC4 compatibility) */ fprintf( stderr, "xnec2c: datagn(): ignoring CM card in geometry\n" ); stop( _("datagn(): Ignoring CM card in geometry"), ERR_OK ); continue; default: /* error message */ fprintf( stderr, "xnec2c: datagn(): geometry data card error\n" ); fprintf( stderr, "%2s %3d %5d %10.5f %10.5f %10.5f" " %10.5f %10.5f %10.5f %10.5f\n", gm, itg, ns, xw1, yw1, zw1, xw2, yw2, zw2, rad ); stop( _("datagn(): Geometry data card error"), ERR_OK ); return( FALSE ); } /* switch( gm_num ) */ } /* do */ while( TRUE ); } /* datagn() */
MStatus OxDnaTranslator::writer (const MFileObject& file, const MString& optionsString, MPxFileTranslator::FileAccessMode mode) { MStatus status; MObjectArray helices; HMEVALUATE_RETURN(status = Model::Helix::AllSelected(helices), status); if (helices.length() == 0) { HMEVALUATE_RETURN(status = Model::Helix::All(helices), status); } if (helices.length() == 0) { MGlobal::displayError("Nothing to export. Aborting..."); return MStatus::kSuccess; } if (!MProgressWindow::reserve()) MGlobal::displayWarning("Failed to reserve the progress window"); MProgressWindow::setTitle("oxDNA Exporter"); MProgressWindow::setProgressStatus("Identifying strands..."); MProgressWindow::setProgressRange(0, helices.length()); MProgressWindow::startProgress(); MVector minTranslation(std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()), maxTranslation(-std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity()); // Since a strand is defined by any base along it, the same strand will be obtained multiple times if we don't track them. // This is pretty slow but, since it is only run once it should be ok. std::list<Model::Strand> strands; for (unsigned int i = 0; i < helices.length(); ++i) { Model::Helix helix(helices[i]); for (Model::Helix::BaseIterator it = helix.begin(); it != helix.end(); ++it) { MVector translation; HMEVALUATE_RETURN(status = it->getTranslation(translation, MSpace::kWorld), status); minTranslation.x = std::min(minTranslation.x, translation.x); minTranslation.y = std::min(minTranslation.y, translation.y); minTranslation.z = std::min(minTranslation.z, translation.z); maxTranslation.x = std::max(maxTranslation.x, translation.x); maxTranslation.y = std::max(maxTranslation.y, translation.y); maxTranslation.z = std::max(maxTranslation.z, translation.z); if (std::find_if(strands.begin(), strands.end(), std::bind2nd(std::ptr_fun(&Model::Strand::Contains_base), *it)) == strands.end()) strands.push_back(*it); } MProgressWindow::advanceProgress(1); } MProgressWindow::endProgress(); if (!MProgressWindow::reserve()) MGlobal::displayWarning("Failed to reserve the progress window"); MProgressWindow::setTitle("oxDNA Exporter"); MProgressWindow::setProgressStatus("Writing strands..."); MProgressWindow::setProgressRange(0, helices.length()); MProgressWindow::startProgress(); OxDnaExporterWithAdvanceProgress exporter; HMEVALUATE(std::for_each(strands.begin(), strands.end(), exporter.execute()), exporter.status()); MProgressWindow::endProgress(); if (!exporter.status()) return exporter.status(); MString top_filename, conf_filename, vhelix_filename; get_filenames(file, top_filename, conf_filename, vhelix_filename); HMEVALUATE_RETURN(status = exporter.write( top_filename.asChar(), conf_filename.asChar(), vhelix_filename.asChar(), minTranslation, maxTranslation), status); return status; }