int main(int argc,char* argv[]) { /* Parse the command line: */ SharedJelloServer::Index numAtoms(4,4,8); SharedJelloServer::Box domain(SharedJelloServer::Box::Point(-60.0,-36.0,0.0),SharedJelloServer::Box::Point(60.0,60.0,96.0)); int listenPortID=-1; // Assign any free port double updateTime=0.02; // Aim for 50 updates/sec for(int i=1;i<argc;++i) { if(argv[i][0]=='-') { if(strcasecmp(argv[i]+1,"numAtoms")==0) { /* Read the number of atoms: */ ++i; for(int j=0;j<3&&i<argc;++j,++i) numAtoms[j]=atoi(argv[i]); } else if(strcasecmp(argv[i]+1,"domain")==0) { /* Read the simulation domain: */ ++i; for(int j=0;j<3&&i<argc;++j,++i) domain.min[j]=SharedJelloServer::Box::Scalar(atof(argv[i])); for(int j=0;j<3&&i<argc;++j,++i) domain.max[j]=SharedJelloServer::Box::Scalar(atof(argv[i])); } else if(strcasecmp(argv[i]+1,"port")==0) { /* Read the server listening port: */ ++i; if(i<argc) listenPortID=atoi(argv[i]); } else if(strcasecmp(argv[i]+1,"tick")==0) { /* Read the server update time interval: */ ++i; if(i<argc) updateTime=atof(argv[i]); } } } /* Ignore SIGPIPE and leave handling of pipe errors to TCP sockets: */ struct sigaction sigPipeAction; sigPipeAction.sa_handler=SIG_IGN; sigemptyset(&sigPipeAction.sa_mask); sigPipeAction.sa_flags=0x0; sigaction(SIGPIPE,&sigPipeAction,0); /* Create a shared Jell-O server: */ SharedJelloServer sjs(numAtoms,domain,listenPortID); std::cout<<"SharedJelloServer::main: Created Jell-O server listening on port "<<sjs.getListenPortID()<<std::endl<<std::flush; /* Run the simulation loop full speed: */ Misc::Timer timer; double lastFrameTime=timer.peekTime(); double nextUpdateTime=timer.peekTime()+updateTime; int numFrames=0; while(true) { /* Calculate the current time step duration: */ double newFrameTime=timer.peekTime(); double timeStep=newFrameTime-lastFrameTime; lastFrameTime=newFrameTime; /* Perform a simulation step: */ sjs.simulate(timeStep); ++numFrames; /* Check if it's time for a state update: */ if(lastFrameTime>=nextUpdateTime) { /* Send a state update to all connected clients: */ sjs.sendServerUpdate(); // std::cout<<"\rFrame rate: "<<double(numFrames)/updateTime<<" fps"<<std::flush; nextUpdateTime+=updateTime; numFrames=0; } } return 0; }
void Molecule::addHydrogens(Atom *a, const QList<unsigned long> &atomIds, const QList<unsigned long> &bondIds) { if (atomIds.size() != bondIds.size()) { qDebug() << "Error, addHydrogens called with atom & bond id lists of different size!"; } // Construct an OBMol, call AddHydrogens and translate the changes OpenBabel::OBMol obmol = OBMol(); if (a) { OpenBabel::OBAtom *obatom = obmol.GetAtom(a->index()+1); // Set implicit valence for unusual elements not handled by OpenBabel // PR#2803076 switch (obatom->GetAtomicNum()) { case 3: case 11: case 19: case 37: case 55: case 85: case 87: obatom->SetImplicitValence(1); obatom->SetHyb(1); obmol.SetImplicitValencePerceived(); break; case 4: case 12: case 20: case 38: case 56: case 88: obatom->SetImplicitValence(2); obatom->SetHyb(2); obmol.SetImplicitValencePerceived(); break; case 84: // Po obatom->SetImplicitValence(2); obatom->SetHyb(3); obmol.SetImplicitValencePerceived(); break; default: // do nothing break; } obmol.AddHydrogens(obatom); } else obmol.AddHydrogens(); // All new atoms in the OBMol must be the additional hydrogens unsigned int numberAtoms = numAtoms(); int j = 0; for (unsigned int i = numberAtoms+1; i <= obmol.NumAtoms(); ++i, ++j) { if (obmol.GetAtom(i)->IsHydrogen()) { OpenBabel::OBAtom *obatom = obmol.GetAtom(i); Atom *atom; if (atomIds.isEmpty()) atom = addAtom(); else if (j < atomIds.size()) atom = addAtom(atomIds.at(j)); else { qDebug() << "Error - not enough unique ids in addHydrogens."; break; } atom->setOBAtom(obatom); // Get the neighbor atom OpenBabel::OBBondIterator iter; OpenBabel::OBAtom *next = obatom->BeginNbrAtom(iter); Bond *bond; if (bondIds.isEmpty()) bond = addBond(); else // Already confirmed by atom ids bond = addBond(bondIds.at(j)); bond->setEnd(Molecule::atom(atom->index())); bond->setBegin(Molecule::atom(next->GetIdx()-1)); } } for (unsigned int i = 1; i <= numberAtoms; ++i) { // Warning -- OB atom index off-by-one here atom(i-1)->setPartialCharge(obmol.GetAtom(i)->GetPartialCharge()); } }
SharedJello::SharedJello(int& argc,char**& argv,char**& appDefaults) :Vrui::Application(argc,argv,appDefaults), pipe(0), newParameterVersion(1),parameterVersion(1), lockedIndex(0),mostRecentIndex(1), nextDraggerID(0), mainMenu(0),settingsDialog(0) { /* Parse the command line: */ const char* serverHostName=0; int serverPortID=-1; bool renderDomainBox=true; for(int i=0;i<argc;++i) { if(argv[i][0]=='-') { if(strcasecmp(argv[i]+1,"host")==0) { ++i; if(i<argc) serverHostName=argv[i]; else std::cerr<<"SharedJello::SharedJello: Ignored dangling -host option"<<std::endl; } else if(strcasecmp(argv[i]+1,"port")==0) { ++i; if(i<argc) serverPortID=atoi(argv[i]); else std::cerr<<"SharedJello::SharedJello: Ignored dangling -port option"<<std::endl; } else if(strcasecmp(argv[i]+1,"nobox")==0) renderDomainBox=false; } } if(serverHostName==0||serverPortID<0) Misc::throwStdErr("SharedJello::SharedJello: No server host name or port ID provided"); /* Connect to the shared Jell-O server: */ pipe=Cluster::openTCPPipe(Vrui::getClusterMultiplexer(),serverHostName,serverPortID); pipe->negotiateEndianness(); /* Initiate the connection: */ if(readMessage(*pipe)!=CONNECT_REPLY) { /* Bail out: */ pipe=0; Misc::throwStdErr("SharedJello::SharedJello: Connection refused by shared Jell-O server"); } /* Read the Jell-O crystal's domain box: */ read(domain,*pipe); /* Read the number of atoms in the Jell-O crystal: */ Card na[3]; pipe->read(na,3); JelloCrystal::Index numAtoms(na[0],na[1],na[2]); /* Wait for the first parameter update message to get the initial simulation parameters: */ if(readMessage(*pipe)!=SERVER_PARAMUPDATE) { /* Bail out: */ pipe=0; Misc::throwStdErr("SharedJello::SharedJello: Connection refused by shared Jell-O server"); } atomMass=pipe->read<Scalar>(); attenuation=pipe->read<Scalar>(); gravity=pipe->read<Scalar>(); /* Wait for the first server update message to get initial atom positions: */ if(readMessage(*pipe)!=SERVER_UPDATE) { /* Bail out: */ pipe=0; Misc::throwStdErr("SharedJello::SharedJello: Connection refused by shared Jell-O server"); } /* Create triple buffer of Jell-O crystals: */ for(int i=0;i<3;++i) crystals[i]=new JelloCrystal(numAtoms); /* Read the first crystal state: */ crystals[mostRecentIndex]->readAtomStates(*pipe); /* Calculate the domain box color: */ GLColor<GLfloat,3> domainBoxColor; for(int i=0;i<3;++i) domainBoxColor[i]=1.0f-Vrui::getBackgroundColor()[i]; /* Create the triple buffer of Jell-O renderers: */ for(int i=0;i<3;++i) { renderers[i]=new JelloRenderer(*crystals[i]); renderers[i]->setRenderDomainBox(renderDomainBox); renderers[i]->setDomainBoxColor(domainBoxColor); } renderers[mostRecentIndex]->update(); /* Start the server communication thread: */ communicationThread.start(this,&SharedJello::communicationThreadMethod); /* Create the program's user interface: */ mainMenu=createMainMenu(); Vrui::setMainMenu(mainMenu); settingsDialog=createSettingsDialog(); /* Initialize the navigation transformation: */ centerDisplayCallback(0); }