Example #1
0
static Bool _InitRenderFn(HairVideoPost* vp, VolumeData* vd, BaseDocument* doc, BaseList2D* bl, HairObject* op, HairGuides* guides, Int32 oindex, Int32 pass)
{
	//GePrint("Init Render");

	BaseContainer*		bc	= bl->GetDataInstance();
	HairRenderingTag* hrt = (HairRenderingTag*)bl->GetNodeData();

	if (!bc || !hrt)
		return false;

	hrt->m_Shadow = bc->GetFloat(HAIR_RENDERING_SHADOW);
	hrt->m_Trans	= bc->GetFloat(HAIR_RENDERING_TRANSPARENCY);
	hrt->m_Depth	= bc->GetInt32(HAIR_RENDERING_DEPTH);

	return true;
}
void DropEffector::InitPoints(BaseObject* op, BaseObject* gen, BaseDocument* doc, EffectorDataStruct* data, MoData* md, BaseThread* thread)
{
	BaseContainer* bc = op->GetDataInstance();
	if (!bc)
		return;

	if (!rcol)
		return;

	ed.mode = bc->GetInt32(DROPEFFECTOR_MODE);
	ed.maxdist = bc->GetFloat(DROPEFFECTOR_DISTANCE);
	ed.target	 = bc->GetObjectLink(DROPEFFECTOR_TARGET, doc);
	if (!ed.target)
		return;

	ed.targmg	 = ed.target->GetMg();
	ed.itargmg = ~ed.targmg;
	ed.genmg	= gen->GetMg();
	ed.igenmg = ~ed.genmg;

	//Add a dependency so that the effector will update if the target changes
	AddEffectorDependence(ed.target);

	//Can't init raycollider or the target isn't polygonal, then skip
	if (!rcol->Init(ed.target))
		ed.target = nullptr;
	else if (!ed.target->IsInstanceOf(Opolygon))
		ed.target = nullptr;
}
Bool SmplMatrixDialog::Command(Int32 id, const BaseContainer& msg)
{
	Bool update_settings = false;

	if (preview.Command(id, msg))
		return true;

	switch (id)
	{
		case	GADGET_SMPL_MATRIX_TYPE_POPUP:
		{
			Int32	type;

			preview.ChangedSettings();	// stop running threads before settings are changed
			type = msg.GetInt32(BFM_ACTION_VALUE);
			if (settings->emr)
			{
				delete_effect_matrix(settings->emr);
				settings->emr = 0;
			}

			settings->type	= type;
			update_settings = true;	// indicates changed effect settings

			break;
		}
		case	GADGET_SMPL_MATRIX_SLIDER_ANGLE:
		{
			Float32	slider_value;

			slider_value = (Float32)Deg(msg.GetFloat(BFM_ACTION_VALUE));
			if (real_time || (msg.GetInt32(BFM_ACTION_INDRAG) == false))
			{
				if (settings->angle != slider_value)
				{
					preview.ChangedSettings();	// stop running threads before settings are changed
					settings->angle = slider_value;
					update_settings = true;			// indicates changed effect settings
				}
			}
			break;
		}
		case	GADGET_SMPL_MATRIX_SLIDER_MIX:
		{
			Float32	slider_value;

			slider_value = (Float32)msg.GetFloat(BFM_ACTION_VALUE);
			if (real_time || msg.GetInt32(BFM_ACTION_INDRAG) == false)
			{
				if (settings->matrix_opacity != slider_value)
				{
					preview.ChangedSettings();	// stop running threads before settings are changed
					settings->matrix_opacity = slider_value;
					update_settings = true;			// indicates changed effect settings
				}
			}
			break;
		}
		case	GADGET_SMPL_MATRIX_TEXTURE_MODE:
		{
			preview.ChangedSettings();	// stop running threads before settings are changed
			settings->tile_flags = msg.GetInt32(BFM_ACTION_VALUE) ? TILE_REPEAT_TILING : TILE_REPEAT_BORDER;
			update_settings = true;
			break;
		}
		case	GADGET_SMPL_MATRIX_DOCUMENT_PREVIEW:
		{
			document_preview = msg.GetInt32(BFM_ACTION_VALUE);
			preview.SetDocumentPreview(document_preview);
			break;
		}
	}

	if (update_settings)
	{
		change_effect_matrix(settings, bm);
		preview.Update();
	}

	return true;
}
/*********************************************************************\
	Function name    : CDialogCustomElement::Save
	Description      :
	Created at       : 27.03.02, @ 14:54:04
	Created by       : Thomas Kunert
	Modified by      :
\*********************************************************************/
Bool CDialogCustomElement::Save(BaseFile* pFile, String strFill)
{
    if (g_pCustomElements && m_lElement >= 0 && m_lElement < g_pCustomElements->Entries())
    {
        CustomProperty* pProp;

        CCustomElements* pElement = g_pCustomElements->GetItem(m_lElement);
        if (!pElement) return true;
        if (!m_pbcGUI) return false;
        BaseContainer* pBC = &m_pbcGUI[m_lElement];

        pProp = pElement->m_pProp;

        WriteString(pFile, pElement->m_pChResSym);
        WriteString(pFile, " ");
        WriteString(pFile, m_strControlID);
        LineBreak(pFile, strFill);

        WriteString(pFile, "{");
        LineBreak(pFile, strFill + *g_pstrFillSave);
        SaveAlignment(pFile);
        LineBreak(pFile, strFill);

        if (pElement->m_bIsOpen)
        {
            WriteString(pFile, *g_pstrFillSave);
            WriteString(pFile, "OPEN");
            WriteString(pFile, "; ");
            LineBreak(pFile, strFill);
        }

        Int32 i;
        for (i = 0; pProp && pProp[i].type != CUSTOMTYPE_END; i++)
        {
            Bool b = false;
            if (pProp[i].type == CUSTOMTYPE_FLAG)
            {
                if (pBC->GetBool(pProp[i].id))
                {
                    WriteString(pFile, *g_pstrFillSave);
                    WriteString(pFile, pProp[i].ident);
                    WriteString(pFile, "; ");
                    b = true;
                }
            }
            else if (pProp[i].type == CUSTOMTYPE_LONG)
            {
                WriteString(pFile, *g_pstrFillSave);
                WriteString(pFile, pProp[i].ident);
                WriteString(pFile, " ");
                WriteString(pFile, String::IntToString(pBC->GetInt32(pProp[i].id)));

                // XXX: BITMAPBUTTON SIZE is a CUSTOMTYPE_LONG property, yet it
                // requires a tuple for the SIZE parameter. Can we find a better
                // way than hardcoding this?
                // https://github.com/nr-plugins/resedit/issues/2
                if (String(pElement->m_pChResSym) == String("BITMAPBUTTON") &&
                        String(pProp[i].ident) == String("SIZE")) {
                    WriteString(pFile, ", ");
                    WriteString(pFile, String::IntToString(pBC->GetInt32(pProp[i].id)));
                }

                WriteString(pFile, "; ");
                b = true;
            }
            else if (pProp[i].type == CUSTOMTYPE_REAL)
            {
                WriteString(pFile, *g_pstrFillSave);
                WriteString(pFile, pProp[i].ident);
                WriteString(pFile, " ");
                WriteString(pFile, String::FloatToString(pBC->GetFloat(pProp[i].id)));
                WriteString(pFile, "; ");
                b = true;
            }
            else if (pProp[i].type == CUSTOMTYPE_STRING)
            {
                if (pBC->GetString(pProp[i].id).Content())
                {
                    WriteString(pFile, *g_pstrFillSave);
                    WriteString(pFile, pProp[i].ident);
                    WriteString(pFile, " ");
                    WriteString(pFile, pBC->GetString(pProp[i].id));
                    WriteString(pFile, "; ");
                    b = true;
                }
            }
            else if (pProp[i].type == CUSTOMTYPE_VECTOR)
            {
                WriteString(pFile, *g_pstrFillSave);
                WriteString(pFile, pProp[i].ident);
                WriteString(pFile, " ");
                WriteString(pFile, String::FloatToString(pBC->GetVector(pProp[i].id).x));
                WriteString(pFile, " ");
                WriteString(pFile, String::FloatToString(pBC->GetVector(pProp[i].id).y));
                WriteString(pFile, " ");
                WriteString(pFile, String::FloatToString(pBC->GetVector(pProp[i].id).z));
                WriteString(pFile, " ");
                WriteString(pFile, "; ");
                b = true;
            }

            if (b)
                LineBreak(pFile, strFill);
        }
        WriteString(pFile, "}");
    }

    return true;
}
Example #5
0
Bool LiquidToolData::MouseInput(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, EditorWindow* win, const BaseContainer& msg)
{
	Float mx = msg.GetFloat(BFM_INPUT_X);
	Float my = msg.GetFloat(BFM_INPUT_Y);
	Int32 button;

	switch (msg.GetInt32(BFM_INPUT_CHANNEL))
	{
		case BFM_INPUT_MOUSELEFT: button	= KEY_MLEFT; break;
		case BFM_INPUT_MOUSERIGHT: button = KEY_MRIGHT; break;
		default: return true;
	}

	BaseObject* cl = nullptr, *null = nullptr, *op = nullptr;
	Float				dx, dy, rad = 5.0;
	Bool				newmeta = false;

	op = BaseObject::Alloc(Osphere);
	if (!op)
		return false;

	null = BaseObject::Alloc(Ometaball);
	{
		null->GetDataInstance()->SetFloat(METABALLOBJECT_SUBEDITOR, 10.0);
		null->MakeTag(Tphong);
	}
	newmeta = true;

	if (newmeta)
	{
		doc->InsertObject(null, nullptr, nullptr);
		doc->SetActiveObject(null);

		doc->AddUndo(UNDOTYPE_NEW, null);

		DrawViews(DRAWFLAGS_ONLY_ACTIVE_VIEW | DRAWFLAGS_NO_THREAD | DRAWFLAGS_NO_ANIMATION);
	}

	BaseContainer bc;
	BaseContainer device;
	win->MouseDragStart(button, mx, my, MOUSEDRAGFLAGS_DONTHIDEMOUSE | MOUSEDRAGFLAGS_NOMOVE);
	while (win->MouseDrag(&dx, &dy, &device) == MOUSEDRAGRESULT_CONTINUE)
	{
		bc = BaseContainer();
		win->BfGetInputEvent(BFM_INPUT_MOUSE, &bc);
		if (bc.GetInt32(BFM_INPUT_CHANNEL) == BFM_INPUT_MOUSEWHEEL)
		{
			rad += bc.GetFloat(BFM_INPUT_VALUE) / 120.0;
			rad	 = ClampValue(rad, (Float) 0.1, (Float) MAXRANGE);
			GePrint(String::FloatToString(rad));
		}

		if (dx == 0.0 && dy == 0.0)
			continue;

		mx += dx;
		my += dy;
		cl	= (BaseObject*)op->GetClone(COPYFLAGS_0, nullptr);
		if (!cl)
			break;

		cl->GetDataInstance()->SetFloat(PRIM_SPHERE_RAD, rad);

		cl->SetAbsPos(bd->SW(Vector(mx, my, 500.0)));
		cl->InsertUnder(null);
		DrawViews(DRAWFLAGS_ONLY_ACTIVE_VIEW | DRAWFLAGS_NO_THREAD | DRAWFLAGS_NO_ANIMATION);
	}

	if (win->MouseDragEnd() == MOUSEDRAGRESULT_ESCAPE)
	{
		doc->DoUndo(true);
	}

	BaseObject::Free(op);

	EventAdd();
	return true;
}
Example #6
0
BaseObject* VoxelGenerator::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
{	
	BaseContainer* data = op->GetDataInstance();
	BaseDocument* doc = op->GetDocument();

	/************************************************************************/
	Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA);
	if (!dirty)
		return op->GetCache(hh);
	
	/************************************************************************/
	Float t_scale		= data->GetFloat(VGEN_SCALE); if(t_scale == 0.0) return nullptr;
	Float t_threshold	= data->GetFloat(VGEN_THRESHOLD);

	Vector scale(t_scale); //Just the vector version of the uniform scale
		
	/************************************************************************/
	//Get the Effex Server (which contains all effex scenes)
	FXAPI::FXServer *server		= FXAPI::FXServer::Get(doc); if(!server) return nullptr;

	//Get the scalar channel's BaseObject interface from the link field
	BaseObject* channel_object	= op->GetDataInstance()->GetObjectLink(VGEN_CHANNEL, doc); if(!channel_object) return nullptr;
	
	//Find the Effex scene the scalar channel belongs to
	FXAPI::FXScene* effex_scene = server->GetEffexScene(channel_object); if(!effex_scene) return nullptr;	
	
	//Finally retrieve the scalar channel node from the effex scene */
	FXAPI::FXScalarChannel* ptr_channel = static_cast<FXAPI::FXScalarChannel*>(FXAPI::GetNode(effex_scene,channel_object,FXAPI::NodeRetrieveType_ScalarChannel));
	if(!ptr_channel) return nullptr;

	/************************************************************************/
	//We wanna place all voxel cubes under this null object
	BaseObject* ret = BaseObject::Alloc(Onull); if(!ret) { return nullptr; }
	//Create a reference cube
	BaseObject* voxel_cube = BaseObject::Alloc(Ocube); if(!voxel_cube) return ret;
	//Set Normal scale
	voxel_cube->GetDataInstance()->SetVector(PRIM_CUBE_LEN, Vector(1.0));
	//Renaming the cube
	voxel_cube->SetName("Voxel Reference");
	//Tell the cube to update bounding box etc.
	voxel_cube->Message(MSG_UPDATE);
	//Finally place the cube under our null object
	voxel_cube->InsertUnder(ret);
	
	/************************************************************************/
	//Now we create a scalar cell iterator which lets us browse all cells of a scalar channel
	//You can use C4D's AutoAlloc class for scope based construction/destruction
	//Otherwise just use FXAPI::FXScalarCellIterator::Alloc/Free
	AutoAlloc<FXAPI::FXScalarCellIterator> iterator;

	//Initialise it with our scalar channel, the cpu threads count we use and if grid border cells should be browsed as well
	if(iterator->Init(ptr_channel, 1, true)) 
	{
		/************************************************************************/
		/* The following part could be called from multiple cpu threads			*/
		/* but here we stay single-threaded										*/
		/************************************************************************/
		Int32 cpu_index = 0; //First cpu = 0

		//Call once per thread
		iterator->Start(cpu_index,false); //passing true would give a reverse iterator

		do //Now we browse with a do...while loop all cells of this cpu
		{
			//The iterator gives us the current cell value 
			double cell_scalar_value = iterator->GetValue(cpu_index);

			//Example: check for value threshold to only create instances in cells containing a value (e.g. smoke density)
			if(cell_scalar_value <= t_threshold)
				continue; //don't process this cell

			//Get the current cell's coordinate (in grid cell space)
			NAVIE_GLOBAL::VecInt3D xyz_cell = iterator->GetCoordinate(cpu_index);

			//Now convert coordinates from grid cell space to world space coordinates
			//which we will use to set the cube instances's position
			NAVIE_GLOBAL::vector3d xyz_global;
			if(FXAPI::GridToWorld(ptr_channel, xyz_cell, xyz_global, false)) 
			{
				//Conversion was fine. Now we create an instance object for this cell				
				BaseObject* voxel_instance = BaseObject::Alloc(Oinstance); if(!voxel_instance) continue;	
				//Set the reference voxel cube as source
				voxel_instance->GetDataInstance()->SetLink(INSTANCEOBJECT_LINK, voxel_cube);
				//Make it a render instance
				voxel_instance->GetDataInstance()->SetBool(INSTANCEOBJECT_RENDERINSTANCE, true); 
				//Renaming the instance to Voxel + its linear coordinate index
				voxel_instance->SetName("Voxel Reference" + String::IntToString(iterator->GetLinearCoordinate(cpu_index)));	

				//Set position (converting from an Effex vector3d to a c4d Vector on the fly)
				voxel_instance->SetAbsPos(FXAPI::Vec3DToVector(xyz_global));			
				//We also control the scale by the scalar cell value
				voxel_instance->SetAbsScale(scale * cell_scalar_value);
				
				//Tell the instance to update all its data
				voxel_instance->Message(MSG_UPDATE);
				//Finally place the instance under our null object
				voxel_instance->InsertUnderLast(ret);				
			}

		} while(iterator->SetNext(cpu_index)); //Go to next cell..
		/************************************************************************/
	}

	return ret;
}