void GUIMainWindow::OnFindMaxTSD(wxCommandEvent &event) { //ist ein Objekt geladen? if (wxGetApp().getCurrentDataObjectIndex() > -1) { //aktuelles Objekt ObjectData* obj = wxGetApp().getActiveObject(); //Ist die Temperaturverteilung aktuell? if (obj->getCurrentSensorIndex() != propbox->getSensorDataList()->GetSelection()) { wxMessageBox( wxT( "Das Objekt wurde noch nicht neu berechnet!\nBitte berechnen sie das Objekt neu, um die Maximumssuche fortzusetzen!"), wxT("Fehler")); return; } //zu verwendende Methode erfragen wxMessageDialog dlg(this, wxT("Nur Messwertdurchschnitt verwenden? (schneller)"), wxT("Schnelle Methode verwenden?"), wxYES_NO | wxYES_DEFAULT | wxCANCEL); int res = dlg.ShowModal(); //Soll fortgefahren werden? if (res != wxID_CANCEL) { propbox->getSdTimeline()->findMaxValue(obj, (res == wxID_YES)); } } }
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(); } }