--User changes

Implement copying and pasting xforms between flames.

--Code changes
 Make palette filename be a shared_ptr<string> to avoid duplication.
 Ensure random seeds in RendererCL have no duplicates and are not zero.
This commit is contained in:
mfeemster 2015-05-19 19:31:33 -07:00
parent 48ccce69f6
commit cb54605878
9 changed files with 106 additions and 8 deletions

View File

@ -87,6 +87,7 @@ public:
m4T ToMat4ColMajor(bool center = false) const; m4T ToMat4ColMajor(bool center = false) const;
m4T ToMat4RowMajor(bool center = false) const; m4T ToMat4RowMajor(bool center = false) const;
//Note that returning a copy is actually faster than a const ref&.
T A() const; T A() const;
T B() const; T B() const;
T C() const; T C() const;

View File

@ -578,7 +578,7 @@ public:
int m_Index;//Index in the xml palette file of this palette, use -1 for random. int m_Index;//Index in the xml palette file of this palette, use -1 for random.
string m_Name;//Name of this palette. string m_Name;//Name of this palette.
string m_Filename;//Name of the parent file this palette came from, can be empty. shared_ptr<string> m_Filename;//Name of the parent file this palette came from, can be empty.
vector<v4T> m_Entries;//Storage for the color values. vector<v4T> m_Entries;//Storage for the color values.
}; };
} }

View File

@ -51,11 +51,12 @@ public:
if (doc != nullptr) if (doc != nullptr)
{ {
xmlNode* rootNode = xmlDocGetRootElement(doc); auto rootNode = xmlDocGetRootElement(doc);
auto pfilename = shared_ptr<string>(new string(filename));
palettes.clear(); palettes.clear();
palettes.reserve(buf.size() / 2048);//Roughly what it takes per palette. palettes.reserve(buf.size() / 2048);//Roughly what it takes per palette.
ParsePalettes(rootNode, filename, palettes); ParsePalettes(rootNode, pfilename, palettes);
xmlFreeDoc(doc); xmlFreeDoc(doc);
added = true; added = true;
} }
@ -226,7 +227,7 @@ private:
/// <param name="node">The parent note of all palettes in the Xml file.</param> /// <param name="node">The parent note of all palettes in the Xml file.</param>
/// <param name="filename">The name of the Xml file.</param> /// <param name="filename">The name of the Xml file.</param>
/// <param name="palettes">The vector to store the paresed palettes associated with this file in.</param> /// <param name="palettes">The vector to store the paresed palettes associated with this file in.</param>
void ParsePalettes(xmlNode* node, const string& filename, vector<Palette<T>>& palettes) void ParsePalettes(xmlNode* node, const shared_ptr<string>& filename, vector<Palette<T>>& palettes)
{ {
bool hexError = false; bool hexError = false;
char* val; char* val;

View File

@ -1475,18 +1475,23 @@ CarToRasCL<T> RendererCL<T>::ConvertCarToRas(const CarToRas<T>& carToRas)
/// <summary> /// <summary>
/// Fill seeds buffer which gets passed to the iteration kernel. /// Fill seeds buffer which gets passed to the iteration kernel.
/// The range of each seed will be spaced to ensure no duplicates are added.
/// Note, WriteBuffer() must be called after this to actually copy the /// Note, WriteBuffer() must be called after this to actually copy the
/// data from the host to the device. /// data from the host to the device.
/// </summary> /// </summary>
template <typename T> template <typename T>
void RendererCL<T>::FillSeeds() void RendererCL<T>::FillSeeds()
{ {
double start, delta = std::floor((double)std::numeric_limits<uint>::max() / (IterGridKernelCount() * 2));
m_Seeds.resize(IterGridKernelCount()); m_Seeds.resize(IterGridKernelCount());
start = delta;
for (auto& seed : m_Seeds) for (auto& seed : m_Seeds)
{ {
seed.x = m_Rand[0].Rand(); seed.x = (uint)m_Rand[0].Frand<double>(start, start + delta);
seed.y = m_Rand[0].Rand(); start += delta;
seed.y = (uint)m_Rand[0].Frand<double>(start, start + delta);
start += delta;
} }
} }

View File

@ -121,6 +121,8 @@ public slots:
void OnActionCopyAllXml(bool checked); void OnActionCopyAllXml(bool checked);
void OnActionPasteXmlAppend(bool checked); void OnActionPasteXmlAppend(bool checked);
void OnActionPasteXmlOver(bool checked); void OnActionPasteXmlOver(bool checked);
void OnActionCopySelectedXforms(bool checked);
void OnActionPasteSelectedXforms(bool checked);
void OnActionAddReflectiveSymmetry(bool checked);//Tools. void OnActionAddReflectiveSymmetry(bool checked);//Tools.
void OnActionAddRotationalSymmetry(bool checked); void OnActionAddRotationalSymmetry(bool checked);

View File

@ -170,6 +170,9 @@
<addaction name="ActionCopyAllXml"/> <addaction name="ActionCopyAllXml"/>
<addaction name="ActionPasteXmlAppend"/> <addaction name="ActionPasteXmlAppend"/>
<addaction name="ActionPasteXmlOver"/> <addaction name="ActionPasteXmlOver"/>
<addaction name="separator"/>
<addaction name="ActionCopySelectedXforms"/>
<addaction name="ActionPasteSelectedXforms"/>
</widget> </widget>
<addaction name="MenuFile"/> <addaction name="MenuFile"/>
<addaction name="MenuEdit"/> <addaction name="MenuEdit"/>
@ -6104,7 +6107,7 @@ SpinBox
<normaloff>:/Fractorium/Icons/page_paste.png</normaloff>:/Fractorium/Icons/page_paste.png</iconset> <normaloff>:/Fractorium/Icons/page_paste.png</normaloff>:/Fractorium/Icons/page_paste.png</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Paste Xml &amp;Append</string> <string>Paste Xml A&amp;ppend</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+V</string> <string>Ctrl+V</string>
@ -6139,6 +6142,28 @@ SpinBox
<string>Fl&amp;ip</string> <string>Fl&amp;ip</string>
</property> </property>
</action> </action>
<action name="ActionCopySelectedXforms">
<property name="text">
<string>Copy Selected &amp;Xforms</string>
</property>
<property name="toolTip">
<string>Copy selected xforms to the clipboard</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="ActionPasteSelectedXforms">
<property name="text">
<string>Paste Selected X&amp;forms</string>
</property>
<property name="toolTip">
<string>Paste copied xforms into the current flame</string>
</property>
<property name="shortcut">
<string>Ctrl+W</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

View File

@ -94,6 +94,8 @@ public:
virtual void CopyAllXml() { } virtual void CopyAllXml() { }
virtual void PasteXmlAppend() { } virtual void PasteXmlAppend() { }
virtual void PasteXmlOver() { } virtual void PasteXmlOver() { }
virtual void CopySelectedXforms() { }
virtual void PasteSelectedXforms() { }
virtual void AddReflectiveSymmetry() { }//Tools. virtual void AddReflectiveSymmetry() { }//Tools.
virtual void AddRotationalSymmetry() { } virtual void AddRotationalSymmetry() { }
virtual void AddBothSymmetry() { } virtual void AddBothSymmetry() { }
@ -323,6 +325,8 @@ public:
virtual void CopyAllXml() override; virtual void CopyAllXml() override;
virtual void PasteXmlAppend() override; virtual void PasteXmlAppend() override;
virtual void PasteXmlOver() override; virtual void PasteXmlOver() override;
virtual void CopySelectedXforms() override;
virtual void PasteSelectedXforms() override;
virtual void AddReflectiveSymmetry() override; virtual void AddReflectiveSymmetry() override;
virtual void AddRotationalSymmetry() override; virtual void AddRotationalSymmetry() override;
virtual void AddBothSymmetry() override; virtual void AddBothSymmetry() override;
@ -477,6 +481,8 @@ private:
Ember<T> m_Ember; Ember<T> m_Ember;
EmberFile<T> m_EmberFile; EmberFile<T> m_EmberFile;
deque<Ember<T>> m_UndoList; deque<Ember<T>> m_UndoList;
vector<Xform<T>> m_CopiedXforms;
Xform<T> m_CopiedFinalXform;
Palette<T> m_TempPalette; Palette<T> m_TempPalette;
PaletteList<T> m_PaletteList; PaletteList<T> m_PaletteList;
VariationList<T> m_VariationList; VariationList<T> m_VariationList;

View File

@ -25,6 +25,9 @@ void Fractorium::InitMenusUI()
connect(ui.ActionCopyAllXml, SIGNAL(triggered(bool)), this, SLOT(OnActionCopyAllXml(bool)), Qt::QueuedConnection); connect(ui.ActionCopyAllXml, SIGNAL(triggered(bool)), this, SLOT(OnActionCopyAllXml(bool)), Qt::QueuedConnection);
connect(ui.ActionPasteXmlAppend, SIGNAL(triggered(bool)), this, SLOT(OnActionPasteXmlAppend(bool)), Qt::QueuedConnection); connect(ui.ActionPasteXmlAppend, SIGNAL(triggered(bool)), this, SLOT(OnActionPasteXmlAppend(bool)), Qt::QueuedConnection);
connect(ui.ActionPasteXmlOver, SIGNAL(triggered(bool)), this, SLOT(OnActionPasteXmlOver(bool)), Qt::QueuedConnection); connect(ui.ActionPasteXmlOver, SIGNAL(triggered(bool)), this, SLOT(OnActionPasteXmlOver(bool)), Qt::QueuedConnection);
connect(ui.ActionCopySelectedXforms, SIGNAL(triggered(bool)), this, SLOT(OnActionCopySelectedXforms(bool)), Qt::QueuedConnection);
connect(ui.ActionPasteSelectedXforms, SIGNAL(triggered(bool)), this, SLOT(OnActionPasteSelectedXforms(bool)), Qt::QueuedConnection);
ui.ActionPasteSelectedXforms->setEnabled(false);
//Tools menu. //Tools menu.
connect(ui.ActionAddReflectiveSymmetry, SIGNAL(triggered(bool)), this, SLOT(OnActionAddReflectiveSymmetry(bool)), Qt::QueuedConnection); connect(ui.ActionAddReflectiveSymmetry, SIGNAL(triggered(bool)), this, SLOT(OnActionAddReflectiveSymmetry(bool)), Qt::QueuedConnection);
@ -609,6 +612,57 @@ void FractoriumEmberController<T>::PasteXmlOver()
void Fractorium::OnActionPasteXmlOver(bool checked) { m_Controller->PasteXmlOver(); } void Fractorium::OnActionPasteXmlOver(bool checked) { m_Controller->PasteXmlOver(); }
/// <summary>
/// Copy the selected xforms.
/// Note this will also copy final if selected.
/// If none selected, just copy current.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::CopySelectedXforms()
{
m_CopiedXforms.clear();
m_CopiedFinalXform.Clear();
UpdateXform([&](Xform<T>* xform)
{
if (m_Ember.IsFinalXform(xform))
m_CopiedFinalXform = *xform;
else
m_CopiedXforms.push_back(*xform);
}, UPDATE_SELECTED, false);
m_Fractorium->ui.ActionPasteSelectedXforms->setEnabled(true);
}
void Fractorium::OnActionCopySelectedXforms(bool checked)
{
m_Controller->CopySelectedXforms();
}
/// <summary>
/// Paste the selected xforms.
/// Note this will also paste/overwrite final if previously copied.
/// Resets the rendering process.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::PasteSelectedXforms()
{
Update([&]()
{
for (auto& it : m_CopiedXforms)
m_Ember.AddXform(it);
if (!m_CopiedFinalXform.Empty())
m_Ember.SetFinalXform(m_CopiedFinalXform);
FillXforms();
});
}
void Fractorium::OnActionPasteSelectedXforms(bool checked)
{
m_Controller->PasteSelectedXforms();
}
/// <summary> /// <summary>
/// Add reflective symmetry to the current ember. /// Add reflective symmetry to the current ember.
/// Resets the rendering process. /// Resets the rendering process.

View File

@ -562,7 +562,11 @@ void FractoriumEmberController<T>::FillParamTablesAndPalette()
//Use the ember's embedded palette, rather than one from the list, so assign it directly to the controls without applying adjustments. //Use the ember's embedded palette, rather than one from the list, so assign it directly to the controls without applying adjustments.
//Normally, the temp palette is assigned whenever the user clicks on a palette cell. But since that is skipped here, must do it manually. //Normally, the temp palette is assigned whenever the user clicks on a palette cell. But since that is skipped here, must do it manually.
m_TempPalette = m_Ember.m_Palette; m_TempPalette = m_Ember.m_Palette;
m_Fractorium->SetPaletteFileComboIndex(m_Ember.m_Palette.m_Filename); auto temp = m_Ember.m_Palette.m_Filename;
if (temp.get())
m_Fractorium->SetPaletteFileComboIndex(*temp.get());
UpdateAdjustedPaletteGUI(m_Ember.m_Palette);//Setting the palette will trigger a full render. UpdateAdjustedPaletteGUI(m_Ember.m_Palette);//Setting the palette will trigger a full render.
} }