void PatchInspector::emitCoords()
{
	PatchNodePtr patch = _patch.lock();

	if (patch == NULL) return;

	// Save the coords into the patch
	UndoableCommand emitCoordsCmd("patchAdjustControlVertex");

	patch->getPatchInternal().undoSave();

	int row = _rowCombo->GetSelection();
	int col = _colCombo->GetSelection();

	// Retrieve the controlvertex
	PatchControl& ctrl = patch->getPatchInternal().ctrlAt(row, col);

	ctrl.vertex[0] = string::convert<float>(_coords["x"].value->GetValue());
	ctrl.vertex[1] = string::convert<float>(_coords["y"].value->GetValue());
	ctrl.vertex[2] = string::convert<float>(_coords["z"].value->GetValue());

	ctrl.texcoord[0] = string::convert<float>(_coords["s"].value->GetValue());
	ctrl.texcoord[1] = string::convert<float>(_coords["t"].value->GetValue());

	patch->getPatchInternal().controlPointsChanged();

	GlobalMainFrame().updateAllWindows();
}
void PatchInspector::setPatch(const PatchNodePtr& newPatch)
{
	// Detach if we had a previous patch
	PatchNodePtr patch = _patch.lock();

	if (patch != NULL)
	{
		patch->getPatch().detachObserver(this);
	}

	// Clear vertex chooser while _patchRows/_patchCols are still set
	clearVertexChooser();

	_patch = newPatch;

	if (newPatch != NULL)
	{
		newPatch->getPatch().attachObserver(this);

		_patchRows = newPatch->getPatch().getHeight();
		_patchCols = newPatch->getPatch().getWidth();

		// Now that rows/cols are known, build lists
		repopulateVertexChooser();
	}
	else
	{
		_patchRows = 0;
		_patchCols = 0;
	}
}
void PatchInspector::loadControlVertex()
{
	PatchNodePtr patch = _patch.lock();

	if (patch != NULL)
	{
		int row = _rowCombo->GetSelection();
		int col = _colCombo->GetSelection();

		// Retrieve the controlvertex
		const PatchControl& ctrl = patch->getPatch().ctrlAt(row, col);

		_updateActive = true;

		_coords["x"].value->SetValue(string::to_string(ctrl.vertex[0]));
		_coords["y"].value->SetValue(string::to_string(ctrl.vertex[1]));
		_coords["z"].value->SetValue(string::to_string(ctrl.vertex[2]));
		_coords["s"].value->SetValue(string::to_string(ctrl.texcoord[0]));
		_coords["t"].value->SetValue(string::to_string(ctrl.texcoord[1]));

		_updateActive = false;
	}
}
void PatchInspector::update()
{
	_updateActive = true;

	PatchNodePtr patch = _patch.lock();

	if (patch != NULL)
	{
		// Check if the matrix size has changed
		if (patch->getPatch().getWidth() != _patchCols ||
			patch->getPatch().getHeight() != _patchRows)
		{
			// Patch matrix got changed
			clearVertexChooser();
			repopulateVertexChooser();
		}

		// Load the data from the currently selected vertex
		loadControlVertex();
	}

	_updateActive = false;
}
Example #5
0
void thicken(const PatchNodePtr& sourcePatch, float thickness, bool createSeams, int axis)
{
	// Get a shortcut to the patchcreator
	PatchCreator& patchCreator = GlobalPatchCreator(DEF2);

	// Create a new patch node
	scene::INodePtr node(patchCreator.createPatch());

	scene::INodePtr parent = sourcePatch->getParent();
	assert(parent != NULL);

	// Insert the node into the same parent as the existing patch
	parent->addChildNode(node);

	// Retrieve the contained patch from the node
	Patch* targetPatch = Node_getPatch(node);

	// Create the opposite patch with the given thickness = distance
	targetPatch->createThickenedOpposite(sourcePatch->getPatchInternal(), thickness, axis);

	// Select the newly created patch
	Node_setSelected(node, true);

	if (createSeams && thickness > 0.0f)
	{
		// Allocate four new patches
		scene::INodePtr nodes[4] = {
			patchCreator.createPatch(),
			patchCreator.createPatch(),
			patchCreator.createPatch(),
			patchCreator.createPatch()
		};

		// Now create the four walls
		for (int i = 0; i < 4; i++)
		{
			// Insert each node into the same parent as the existing patch
			// It's vital to do this first, otherwise these patches won't have valid shaders
			parent->addChildNode(nodes[i]);

			// Retrieve the contained patch from the node
			Patch* wallPatch = Node_getPatch(nodes[i]);

			// Create the wall patch by passing i as wallIndex
			wallPatch->createThickenedWall(sourcePatch->getPatchInternal(), *targetPatch, i);

			if (!wallPatch->isDegenerate())
			{
				// Now select the newly created patch
				Node_setSelected(nodes[i], true);
			}
			else
			{
				rMessage() << "Thicken: Discarding degenerate patch." << std::endl;

				// Remove again
				parent->removeChildNode(nodes[i]);
			}
		}
	}

	// Invert the target patch so that it faces the opposite direction
	targetPatch->InvertMatrix();
}