Esempio n. 1
0
void VoxCad::SetupPhysicsWindow(void)
{
	PhysicsDockWidget = new QDockWidget(this);
	PhysicsDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	PhysicsDlg = new Dlg_Physics(&MainSim, PhysicsDockWidget);
	PhysicsDockWidget->setWidget(PhysicsDlg);
    PhysicsDockWidget->setWindowTitle("Physics Settings");
	PhysicsDockWidget->setVisible(false);


	connect(PhysicsDockWidget->toggleViewAction(), SIGNAL(triggered(bool)), this, SLOT(PhysicsMode(bool)));
	connect(&MainSim, SIGNAL(UpdateText(QString)), PhysicsDlg, SLOT(SetStatusText(QString)));
	connect(&MainSim, SIGNAL(ReqGLUpdate()), this, SLOT(ReqGLUpdateAll()));
	connect(&MainSim, SIGNAL(ReqAddPlotPoint(double)), PhysicsDlg, SLOT(AddPlotPoint(double)), Qt::DirectConnection); 

	connect(&MainSim, SIGNAL(StartExternalGLUpdate()), GLWindow, SLOT(StartAutoRedraw()));
	connect(&MainSim, SIGNAL(StopExternalGLUpdate()), GLWindow, SLOT(StopAutoRedraw()));


	//connect(FEAInfoDlg, SIGNAL(RequestUpdateGL()), this, SLOT(ReqGLUpdateAll()));
	//connect(FEAInfoDlg, SIGNAL(GetCurIndex(int*)), this, SLOT(GetCurGLSelected(int*)));
	//connect(FEAInfoDlg, SIGNAL(GetFEAInfoString(QString*)), &MainFEA, SLOT(GetFEAInfoString(QString*)));
	//connect(FEAInfoDlg, SIGNAL(GetFEAInfoString(int, QString*)), &MainFEA, SLOT(GetFEAInfoString(int, QString*)));
	//connect(FEAInfoDlg, SIGNAL(DoneAnalyzing()), this, SLOT(ForceViewMode(void))); 

	addDockWidget(Qt::RightDockWidgetArea, PhysicsDockWidget);
}
Esempio n. 2
0
void QVX_Sim::EndRecording(void) //stops recording
{
	if (!Recording) return; //if already not recording, don't do anything

	DtThaw();
	GLUpdateEveryNFrame = -1; //make sure update every frame is turned off...
	emit StopExternalGLUpdate(); //stop external display that might be at different speed
	emit StartExternalGLUpdate(DEFAULT_DISPLAY_UPDATE_MS); //start default display rate again

	emit ResetGLWindow();

	Recording = false;
}
Esempio n. 3
0
void QVX_TensileTest::BeginTensileTest(QVX_Environment* pEnvIn, int NumStepIn, double ConvThreshIn, double MixRadiusIn, MatBlendModel ModelIn, double PolyExpIn)
{
	//set up local copy of the environment and object...

//	if (MixRadius != 0)	RenderMixedObject(pEnvIn->pObj, &LocObj, MixRadius); //if there's any mixing, we need to make it...
	//else 
	LocObj = *(pEnvIn->pObj); //otherwise just simulate the original object.
	LocEnv = *pEnvIn; //set local environment params to those of the input
	LocEnv.pObj = &LocObj; //make sure local environment points to local object

	//set up blending if desired
	BlendingEnabled = false;
	if (MixRadiusIn != 0){ //if some blending...
		//check for 2 or fewer materials!
		if (LocObj.GetNumLeafMatInUse() > 2){
			QMessageBox::warning(NULL, "Warning", "Currently blending only supported with 2 or fewer materials. Aborting.");
			return;
		}
		BlendingEnabled = true;
		MixRadius = MixRadiusIn;
		BlendModel = ModelIn;
		PolyExp = PolyExpIn;
	}
	
	NumStep = NumStepIn;
	ConvThresh = ConvThreshIn;
	CurTick = 0;
	TotalTick = NumStep;
	CancelFlag = false;

	std::string Message = "";

	pEnvIn->EnableFloor(false);
	pEnvIn->EnableGravity(false);
	pEnvIn->EnableTemp(false);

	Import(&LocEnv, NULL, &Message);
	EnableSelfCollision(false);

	EnableEquilibriumMode(true);

	SetStopConditionType(SC_MIN_MAXMOVE);
	SetStopConditionValue(ConvThreshIn);
//	SetBondDampZ(1.0);
//	SetSlowDampZ(0.03);

	EnablePlasticity(false);
	EnableFailure(false);

	if (!DoBCChecks()) return;

	CurViewMode = RVM_VOXELS;
	CurViewCol = RVC_STRAIN_EN;
	CurViewVox = RVV_DEFORMED;

	//QString DispMesg;

	OutFilePath = QFileDialog::getSaveFileName(NULL, "Save Tensile Test Results", "", "TXT Files (*.txt)");

	emit StartExternalGLUpdate(33);

	TestRunning = true;
	if (OutFilePath != "") TensileThread.Execute(false);
//	RunTensileTest(&DispMesg);
	if (ProgressMessage != "") QMessageBox::warning(NULL, "warning", QString::fromStdString(ProgressMessage));

}
Esempio n. 4
0
void QVX_Sim::BeginRecording(void) //opens record dialog and begins recording
{
	if (Recording) return; //if we're already recording, don't do anything!

	bool WasPaused = Paused; //pause the sim and remeber whether it was paused or not...
	if (Running && !WasPaused) SimPauseToggle();

	Dlg_VideoCapture VidCapDlg(this);
	if (StopConditionType == SC_MAX_TIME_STEPS) {VidCapDlg.StopEnabled=true; VidCapDlg.CurStopSettings = SS_TIME_STEPS; VidCapDlg.sNumStep = qRound(StopConditionValue);}
	if (StopConditionType == SC_MAX_SIM_TIME) {VidCapDlg.StopEnabled=true; VidCapDlg.CurStopSettings = SS_SIM_TIME; VidCapDlg.sSimTime = StopConditionValue;}
	if (StopConditionType == SC_TEMP_CYCLES) {VidCapDlg.StopEnabled=true; VidCapDlg.CurStopSettings = SS_TEMP_CYCLES; VidCapDlg.sNumCyc = qRound(StopConditionValue);}

	VidCapDlg.UpdateUI();
	VidCapDlg.exec();

	if (VidCapDlg.AcceptedDialog){
		if (VidCapDlg.ResetSimOnBegin) ResetSim();

		emit StopExternalGLUpdate(); //stop external update!
		GLUpdateEveryNFrame = -1; //make sure update every frame is turned off...

		double OutFps = VidCapDlg.OutputFps;
		double OutSpdFctr = VidCapDlg.OutputSpeedFactor;

		switch(VidCapDlg.CurVidSetting){
			case VS_DISPLAY: StartExternalGLUpdate(1000*OutSpdFctr/OutFps); break;
			case VS_SIMULATION: {
					DtFreeze(); //this could be bad for sims with non-linear materials that change dramatically in their stability
					double VideoDt = OutSpdFctr/OutFps; //what the dt step for video should be (in sec)
					if (dt > VideoDt){
						dt = VideoDt; //if simulation timesteps are greater than desired video framerate slow down simulation timesteps
						GLUpdateEveryNFrame=1;
					}
					else { //round dt down so that VideoDt is an even multiple...
						GLUpdateEveryNFrame = (int)(VideoDt/dt) + 1;
						dt = VideoDt/((double)GLUpdateEveryNFrame);
					}

				}
				break;
			case VS_EVERY: GLUpdateEveryNFrame = 1; break;
			default: break;
		}

		if (VidCapDlg.StopEnabled){
			switch (VidCapDlg.CurStopSettings){
				case SS_TIME_STEPS: StopConditionType = SC_MAX_TIME_STEPS; StopConditionValue = (vfloat)VidCapDlg.sNumStep; break;
				case SS_SIM_TIME: StopConditionType = SC_MAX_SIM_TIME; StopConditionValue = (vfloat)VidCapDlg.sSimTime; break;
				case SS_TEMP_CYCLES: StopConditionType = SC_TEMP_CYCLES; StopConditionValue = (vfloat)VidCapDlg.sNumCyc; break;
				default: StopConditionType = SC_NONE;
			}
		}
		else StopConditionType = SC_NONE;

		//reset naming for current files in the selected folder
		VideoOutputFolder=VidCapDlg.CurFolder;
		CurVideoFrameNumber = 0;

		emit ResizeGLWindow(VidCapDlg.WidthPix, VidCapDlg.HeightPix);

		Recording = true;

		if (!Running){ RequestBeginSim(); Running = true;}
		else SimPauseToggle(); //always unpause the simulation if we began recording
	}
	else { //rejected (canceled) return to running or not state.
		if (Running && !WasPaused) SimPauseToggle(); //unpause the simulation if it was running before
	}
}
Esempio n. 5
0
void QVX_Sim::SimLoop(QString* pSimMessage)
{
	std::string tmp; //need to link this up to get info back...
	if (!Import(NULL, NULL, &tmp)) return;

	int Count = 0; //Possibly redundant with internal sim count.
	int LastCount = 0;
	bool IsStillDrawing;
	Vec3D<> CurSelPos;
	QString PosLabel;
	bool InternalEnding = false;
	QString Message, DispMessage;
	std::string RetMsg;
	QTime tLastPlot; //plot point add every...
	QTime tLastStatus; //status text box updated...
//	QTime tLastStatCalc; //simulation max/mins calculated every...
	tLastPlot.start();
	tLastStatus.start();
//	tLastStatCalc.start();

	emit ReqUiUpdate(); //for slider ranges that depend on dt or other sim params
	emit StartExternalGLUpdate(DEFAULT_DISPLAY_UPDATE_MS);
	StopSim = false;
	Running = true;
	Paused = false;

	//initialize the COM at the start of the simulation	
	IniCM=GetCM();
	Vec3D<> LastCM = IniCM;

	int StatusNumber = 1, PlotPointNumber = 1;
	double UpStatEv = 500; //Updates status pane every X ms
	int UpPlotEv = 30; //updates plot every X ms when not plotting every point.
	char PlotDataTypes;
	bool PlotVis, StatusVis;

	while (true){ //do this step...
		if (StopConditionMet()){InternalEnding = true; StatToCalc=CALCSTAT_ALL; UpdateStats(); RetMsg+="Simulation stop condition reached.\n";break;}//if stop condition met...
		
		//figure out what stats we need to calculate
		StatToCalc=CALCSTAT_NONE;

		emit IsPlotVisible(&PlotVis);
		bool PlottingPoint = (LogEvery?true:tLastPlot.elapsed() > PlotPointNumber*UpPlotEv) && PlotVis;
		if (PlottingPoint){ //ensure we calculate the info we want to plot
			emit GetPlotRqdStats(&PlotDataTypes);
			StatToCalc |= PlotDataTypes;
		}
		emit IsStatusTextVisible(&StatusVis);
		bool UpdatingStatus = (tLastStatus.elapsed() > StatusNumber*UpStatEv) && StatusVis;
		if (UpdatingStatus){StatToCalc |= CALCSTAT_COM;} //calc any data we need in the text status box

		bool DrawingGLLocal = (GLUpdateEveryNFrame != -1 && Count%GLUpdateEveryNFrame==0);
		if (DrawingGLLocal || NeedStatsUpdate){ //calc any data we need to draw the opengl view...
			StatToCalc |= StatRqdToDraw();
			NeedStatsUpdate = false;
			if (LockCoMToCenter) StatToCalc |= CALCSTAT_COM;
		}


//		if (tLastStatCalc.elapsed() > StatCalcNumber*30){CalcStat=true; StatCalcNumber++; /*tLastStatCalc.restart();*/}

		if (!TimeStep(&RetMsg)){InternalEnding = true; break;}//if something happened in this timestep

		if (DrawingGLLocal){
			IsStillDrawing = true;
			ReqGLDrawingStatus(&IsStillDrawing);
			while (IsStillDrawing){ //wait to finish drawing the previous timestep before continuing
				LOCALSLEEP(1);
				ReqGLDrawingStatus(&IsStillDrawing); //are 
			}
			emit ReqGLUpdate(); 
		} 

		if (StopSim) break;
		while(Paused){
			ActuallyPaused = true;
			if (StopSim) break; //kick out of the loop if we've stopped...
			LOCALSLEEP(100);
		}

		if(UpdatingStatus){
//			emit IsStatusTextVisible...
			if (CurXSel != -1){PosLabel = "Vox "+QString::number(XtoSIndexMap[CurXSel]) + "(sim)"; CurSelPos = VoxArray[XtoSIndexMap[CurXSel]].GetCurPos()*1000; }//position in mm
			else {PosLabel = "CoM "; CurSelPos = SS.CurCM*1000;} //center of mass in mm if nothing else selected
			Message = "Time " + QString::number(CurTime, 'g', 3) + " Sec" + 
					"\nStep Num " + QString::number(CurStepCount) + 
					"\nTime Step = " + QString::number(dt, 'g', 3)+ " Sec" + 
					"\nDisplay Rate  = "+ QString::number((Count-LastCount)/(UpStatEv/1000.0), 'g', 3)+" Steps/sec" +
					"\n" + PosLabel + " X:"+ QString::number(CurSelPos.x, 'g', 3)+"  Y:"+ QString::number(CurSelPos.y, 'g', 3)+"  Z:"+ QString::number(CurSelPos.z, 'g', 3)+ " mm" +
					"\nCoM Displacement = "+ QString::number((SS.CurCM-IniCM).Length()*1000, 'g', 3)+" mm" +
					"\nCoM Velocity = "+ QString::number((SS.CurCM-LastCM).Length()*1000/(dt*(Count-LastCount)), 'g', 3)+" mm/s\n";
					
			if (pEnv->IsFloorEnabled()) Message += "Voxel touching ground: " + QString::number(GetNumTouchingFloor()) + "\n";

					Message += "\n";
					LastCM = SS.CurCM;
			
			if (LogEvery) ApproxMSperLog = (double)tLastStatus.elapsed()/(Count-LastCount); //only update ms per step if its not fixed by the timer
			LastCount = Count;

			emit UpdateText(Message);
			StatusNumber++;
		}

		if (PlottingPoint){
			if (LogEvery) emit ReqAddPlotPoint(GetCurTime());
			else {
				ApproxMSperLog = UpPlotEv;
				emit ReqAddPlotPoint(GetCurTime());
				PlotPointNumber++;
			}
		}

//		if (StatCalcNumber == INT_MAX){StatCalcNumber=1; tLastStatCalc.restart();} //avoid int rollover for our counters
		if (StatusNumber == INT_MAX){StatusNumber=1; tLastStatus.restart();}
		if (PlotPointNumber == INT_MAX){PlotPointNumber=1; tLastPlot.restart();}


		Count++;
	}

	emit StopExternalGLUpdate();

//	emit SetExternalGLUpdate(false);
	Running = false;
	Paused = false;

	Message = "Time " + QString::number(CurTime, 'g', 3) + " Sec" + 
		"\nStep Num " + QString::number(CurStepCount) + 
		"\nTime Step = " + QString::number(dt, 'g', 3)+ " Sec" + 
		"\n" + PosLabel + " X:"+ QString::number(CurSelPos.x, 'g', 3)+"  Y:"+ QString::number(CurSelPos.y, 'g', 3)+"  Z:"+ QString::number(CurSelPos.z, 'g', 3)+ " mm" +
		"\nCOM_Dist = "+ QString::number((SS.CurCM-IniCM).Length()*1000, 'g', 3)+" mm\n\n";

	RetMsg += "Simulation stopped.\n";
	Message += RetMsg.c_str();
	DispMessage = Message + "\nFinal Conditions:\nStep = " + QString::number(CurStepCount) + "\nTime Step = " + QString::number(dt)+"\nKinetic Energy = " + QString::number(SS.TotalObjKineticE)+"\n" ;
	emit UpdateText(DispMessage);

	if (InternalEnding)	emit SimEndedInternally(RetMsg.c_str());

//	Running = false;



}
void QVX_TensileTest::BeginTensileTest(QVX_Sim* pSim, int NumStepIn, double ConvThreshIn, Vec3D<double> MixRadIn, MatBlendModel ModelIn, double PolyExpIn)
//void QVX_TensileTest::BeginTensileTest(QVX_Environment* pEnvIn, int NumStepIn, double ConvThreshIn, double MixRadiusIn, MatBlendModel ModelIn, double PolyExpIn)
{
	//set up local copy of the environment and object...
	//QVX_Environment* pEnvIn = (QVX_Environment*) pSim->pEnv;

		
	LocObj = *(pSim->pEnv->pObj); //otherwise just simulate the original object.
	LocEnv = *pSim->pEnv; //set local environment params to those of the input
	LocEnv.pObj = &LocObj; //make sure local environment points to local object

	//set up blending if desired
	bool EnableBlending = false;
	if (MixRadIn.x != 0 || MixRadIn.y != 0 || MixRadIn.z != 0){ //if some blending...
		//check for 2 or fewer materials!
		if (LocObj.GetNumLeafMatInUse() > 2){
			QMessageBox::warning(NULL, "Warning", "Currently blending only supported with 2 or fewer materials. Aborting.");
			return;
		}
		EnableBlending = true;
		MixRadius = MixRadIn;
		BlendModel = ModelIn;
		PolyExp = PolyExpIn;

		if (MixRadius.x==0)MixRadius.x = LocObj.GetLatticeDim()/10000; //set to tiny fraction to avoid blowup of exponential function
		if (MixRadius.y==0)MixRadius.y = LocObj.GetLatticeDim()/10000; //set to tiny fraction to avoid blowup of exponential function
		if (MixRadius.z==0)MixRadius.z = LocObj.GetLatticeDim()/10000; //set to tiny fraction to avoid blowup of exponential function

		RenderMixedObject(pSim->pEnv->pObj, &LocObj, MixRadius); //if there's any mixing, we need to make it...

	}
	EnableFeature(VXSFEAT_BLENDING, EnableBlending);
	
	NumStep = NumStepIn;
	ConvThresh = ConvThreshIn;
	CurTick = 0;
	TotalTick = NumStep;
	CancelFlag = false;

	std::string Message = "";

	LocEnv.EnableFloor(false);
	LocEnv.EnableGravity(false);
	LocEnv.EnableTemp(false);

	Import(&LocEnv, NULL, &Message);
	EnableFeature(VXSFEAT_COLLISIONS, false);
	EnableFeature(VXSFEAT_EQUILIBRIUM_MODE, true);
	EnableFeature(VXSFEAT_PLASTICITY, false);
	EnableFeature(VXSFEAT_FAILURE, false);
	EnableFeature(VXSFEAT_VOLUME_EFFECTS, pSim->IsFeatureEnabled(VXSFEAT_VOLUME_EFFECTS)); //enables volume effects according to last set physics sandbox value
	SetStopConditionType(SC_MIN_MAXMOVE);
	SetStopConditionValue(ConvThreshIn);

	if (!DoBCChecks()) return;

	OutFilePath = QFileDialog::getSaveFileName(NULL, "Save Tensile Test Results", GetLastDir(), "TXT Files (*.txt)");
	
	pTensileView->VoxMesh.LinkSimVoxels(this, pTensileView);
	pTensileView->VoxMesh.DefMesh.DrawSmooth=false;

	//match view to current selection of the physics sandbox
	pTensileView->SetCurViewCol(pSim->pSimView->GetCurViewCol());
	pTensileView->SetCurViewMode(pSim->pSimView->GetCurViewMode());
	pTensileView->SetCurViewVox(pSim->pSimView->GetCurViewVox());
	pTensileView->SetViewAngles(pSim->pSimView->GetViewAngles());
	pTensileView->SetViewForce(pSim->pSimView->GetViewForce());
	emit StartExternalGLUpdate(33);

	TestRunning = true;
	if (OutFilePath != "") TensileThread.Execute(false);
//	RunTensileTest(&DispMesg);
	if (ProgressMessage != "") QMessageBox::warning(NULL, "warning", QString::fromStdString(ProgressMessage));

}