void GUIMainWindow::assignCurrentObjectProps() {

	//Ist ein Objekt geladen?
	if (wxGetApp().getCurrentDataObjectIndex() > -1) {
		//aktives Objekt
		ObjectData* obj = wxGetApp().getActiveObject();
		//Punkt als Dezimaltrennzeichen verwenden
		setlocale(LC_NUMERIC, "C");

		//Übertragen der Objekt- und Materialeigenschaften aus der Oberfläche in das Objekt
		obj->setName(string(propbox->getObjNameEdit()->GetValue().ToAscii()));
		obj->setMaxvolume(
				atof(propbox->getMaxVolumeEdit()->GetValue().ToAscii()));
		obj->setQuality(atof(propbox->getQualityEdit()->GetValue().ToAscii()));
		obj->setCurrentSensorIndex(
				propbox->getSensorDataList()->GetSelection());
		SensorData* sd = &obj->getSensorDataList()->at(
				propbox->getSensorDataList()->GetSelection());
		if (sd->timed) {
			sd->current_time_index = propbox->getSdTimeline()->getValue();
		}
		ObjectData::MaterialData* mat = &obj->getMaterials()->at(
				propbox->getCurrentMaterial());
		mat->name = propbox->getMatNameEdit()->GetValue().ToAscii();
		mat->interpolation_mode =
				(Interpolator::InterpolationMode) propbox->getInterpolationModeList()->GetSelection();
		mat->density = atof(propbox->getDensityEdit()->GetValue().ToAscii());
		mat->specificheatcapacity = atof(
				propbox->getSpecificHeatCapEdit()->GetValue().ToAscii());
	}
}
void GUICutRenderWindow::renderImage(wxImage* image) {

	//Speichern der Zeit für die Laufzeitmessung
	timeval tm1;
	gettimeofday(&tm1, NULL);

	int width = imgWidthEdit->GetValue();
	int height = imgHeightEdit->GetValue();

	//aktualisieren der Skala
	canvas->getScalePanel()->refresh(width, height);

	//die Anzahl der zur Berechnung zu verwendenden Kerne
	core_count = threadcountedit->GetValue();

	/*
	 * Versuchen, die Interpolation durch vorgezogenes Testen des zuletzt verwendeten Tetraeders zu beschleunigen.
	 * Diese Option ist verursacht Ungenauigkeiten und bietet zumeist wenig Performancegewinn.
	 * Sie ist deshalb standardmäßig deaktiviert und nicht über die Programmoberfläche aktivierbar.
	 */
	bool use_last_tet = false;

	//zurücksetzen der Grafik
	delete image;
	image = new wxImage(width, height, true);
	image->InitAlpha();

	//Punkt als Dezimaltrennzeichen
	setlocale(LC_NUMERIC, "C");

	//Eigenschaften der Temperaturverteilung
	CutRender_info* info = getCutRenderProperties();
	Triangle* tri = info->tri;
	//X-Achse der Ebene im 3D-Raum
	Vector3D* xvec = tri->getV2()->copy();
	xvec->sub(tri->getV1());
	//Normale der Ebene
	Vector3D* tri_nor = tri->getNormal();
	//Y-Achse der Ebene im 3D-Raum
	Vector3D* yvec = xvec->crossProduct(tri_nor);
	delete tri_nor;
	xvec->normalize();
	yvec->normalize();

	//Das aktive Objekt
	ObjectData* obj = wxGetApp().getActiveObject();

	//Erstellen möglichst einfacher Geometrien für die Materialien
	vector<tetgenio*> bases(obj->getMaterials()->size());
	for (unsigned int i = 0; i < obj->getMaterials()->size(); i++) {
		tetgenio* tri_io = new tetgenio();
		string args = "Q";
		tetrahedralize(const_cast<char*>(args.c_str()),
				obj->getMaterials()->at(i).tetgeninput, tri_io, NULL, NULL);
		bases.at(i) = tri_io;
	}

	//Zurücksetzen des Datenarrays für die Temperaturverteilung
	if (value_img != NULL) {
		delete[] value_img;
	}
	value_img = new float[width * height];

	//Verknüpfen der Ausgabe mit den Temperaturverteilungsdaten und der Grafik
	canvas->setImage(image);
	canvas->setValueImg(value_img);

	//Erstellen des Statusregisters für die Berechnungsthreads
	bool thread_running[core_count];
	for (int i = 0; i < core_count; i++) {
		thread_running[i] = 1;
	}

	//Array für die Thread-Objekts
	vector<thread*> threads = vector<thread*>(0);
	//Array für die Kopierten Sensordaten. Das Kopieren ist erforderlich, da die Threads die Daten verändern (sortieren).
	vector<vector<SensorPoint>> copied_sensor_data =
			vector<vector<SensorPoint>>(core_count);

	//Höhe für die Streifen, die die einzelnen Threads berechnen
	int delta_h = height / core_count;

	//Für alle Threads...
	for (int i = 0; i < core_count; i++) {
		//Die Starthöhe des Threads in der Temperaturverteilung
		int startheight = delta_h * i;

		//eventuelle Korrektur der Streifenhöhe für den letzten Thread
		if (i == core_count - 1) {
			if (startheight + delta_h < height) {
				delta_h = height - startheight;
			}
		}

		//Aktueller Sensordatensatz
		SensorData* dataset = &obj->getSensorDataList()->at(
				obj->getCurrentSensorIndex());
		vector<SensorPoint>* original_sd = &dataset->data.at(
				dataset->current_time_index);
		copied_sensor_data.at(i).resize(original_sd->size());

		//Kopieren der Sensordaten den Thread
		for (int p = 0; p < int(original_sd->size()); p++) {
			copySensorPoint(&original_sd->at(p),
					&copied_sensor_data.at(i).at(p));
		}

		//Starten des Threads
		threads.resize(threads.size() + 1,
				new thread(render_thread, &thread_running[i], value_img, image,
						width, height, startheight, delta_h, info, xvec, yvec,
						tri->getV1(), &bases, obj, &copied_sensor_data.at(i),
						use_last_tet));
	}

	//Pfüfzahl, ob noch Threads laufen
	unsigned int running = 0;

	//Solange threads laufen...
	do {
		//Ausgabe aktualisieren
		canvas->Update();
		canvas->Refresh();

		//ermitteln der Pfüfzahl, ob noch Threads laufen. Wenn diese 0 bleibt, sind alle Threads fertig.
		running = 0;
		for (int i = 0; i < core_count; i++) {
			running = running << 1;
			running += thread_running[i];
		};
	} while (running);

	//Threads zusammenführen
	for (int i = 0; i < core_count; i++) {
		threads.at(i)->join();
		delete threads.at(i);
	}

	//Freigeben des Ebenendreiecks
	for (int i = 0; i < 3; i++) {
		delete tri->getVert(i);
	}
	delete tri;

	//Zeitmessung beenden
	timeval tm2;
	gettimeofday(&tm2, NULL);

	unsigned long long t = 1000 * (tm2.tv_sec - tm1.tv_sec)
			+ (tm2.tv_usec - tm1.tv_usec) / 1000;

	//Ausgeben der Berechnungsdauer auf
	SetTitle(
			wxT(
					"Berechnung abgeschlossen. ( ") + floattowxstr(t / 1000.)+wxT( "s )"));

	//Freigeben der Ressourcen
	delete xvec;
	delete yvec;
	for (unsigned int i = 0; i < obj->getMaterials()->size(); i++) {
		delete bases.at(i);
	}
	delete info;
}
void GUIMainWindow::updateObjectPropGUI() {

	//Ist ein Objekt geladen?
	if (wxGetApp().getCurrentDataObjectIndex() > -1) {
		//Es werden keine Events bezüglich der Oberfläche verarbeitet werden
		updating = true;
		//aktives Objekt
		ObjectData* obj = wxGetApp().getActiveObject();
		//Punkt als Dezimaltrennzeichen verwenden
		setlocale(LC_NUMERIC, "C");

		//Übertragen der Objekt- und Materialeigenschaften in die GUI.
		propbox->SetLabel(
				wxString::FromAscii(
						(obj->getName() + " - Objekteigenschaften:").c_str()));
		propbox->getObjNameEdit()->SetValue(
				wxString::FromAscii(obj->getName().c_str()));
		propbox->getMaxVolumeEdit()->SetValue(
				wxString::FromAscii(floattostr(obj->getMaxvolume()).c_str()));
		propbox->getQualityEdit()->SetValue(
				wxString::FromAscii(floattostr(obj->getQuality()).c_str()));
		propbox->getSensorDataList()->Clear();
		for (unsigned int i = 0; i < obj->getSensorDataList()->size(); i++) {
			propbox->getSensorDataList()->Insert(
					wxString::FromAscii(
							obj->getSensorDataList()->at(i).name.c_str()), i);
		}
		propbox->getSensorDataList()->SetSelection(
				obj->getCurrentSensorIndex());
		propbox->getMatListBox()->Clear();
		for (unsigned int i = 0; i < obj->getMaterials()->size(); i++) {
			propbox->getMatListBox()->Insert(
					wxString::FromAscii(
							obj->getMaterials()->at(i).name.c_str()), i);
		}
		propbox->getMatListBox()->SetSelection(propbox->getCurrentMaterial());
		ObjectData::MaterialData* mat = &obj->getMaterials()->at(
				propbox->getCurrentMaterial());
		propbox->getMatPropBox()->SetLabel(
				wxString::FromAscii(
						(mat->name + " - Materialeigenschaften").c_str()));

		propbox->getInterpolationModeList()->SetSelection(
				mat->interpolation_mode);
		propbox->getDensityEdit()->SetValue(
				wxString::FromAscii(floattostr(mat->density).c_str()));
		propbox->getSpecificHeatCapEdit()->SetValue(
				wxString::FromAscii(
						floattostr(mat->specificheatcapacity).c_str()));
		propbox->getMatNameEdit()->SetValue(
				wxString::FromAscii(mat->name.c_str()));
		propbox->resize();
		updating = false;

		//Oberfläche ist aktuell
		propbox->getUpToDateLbl()->Hide();

		//Anzeige des aktiven Objekts aktualisieren
		int nPos = toolbar->GetToolPos(ID_CHANGE_ACTIVE_OBJ);
		wxToolBarToolBase* pTool = toolbar->RemoveTool(ID_CHANGE_ACTIVE_OBJ);
		pTool->SetLabel(
				wxString::FromAscii(
						("aktives Objekt: " + obj->getName()).c_str()));
		toolbar->InsertTool(nPos, pTool);
		toolbar->Realize();
	}
}