예제 #1
0
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;
	}
예제 #2
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());
    }
}
예제 #3
0
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);
	}