Performance Issue in three.js while creating large number of objects and its solution


Few days back I am creating a demo using three.js library(used for rendering 3D objects). I have added three to four geometry on the scene. It was working just fine as well with animation added to it. But when I have increased the number of the geometry rendered on the scene, performance of the demo decreased significantly. 😦

Page loading time also increased. I have done a small mistake in my codding, and many of us can face same issue sometime, so thought of sharing to save your time.. 🙂

For example lets say I need to create five cylinders on the scene, The code I have written:

for ( var i = 1; i < 6; i ++ ) {
var cylinderOne = new THREE.CylinderGeometry(14, 14, 120, 25, 25, false);
var cylinder = new THREE.Mesh(cylinderOne, new THREE.MeshNormalMaterial());
cylinder.position.x = 10*i;
scene.add(cylinder);
}

In the above code it is adding five cylinders to the scene. The issue in the code is in the following line:
var cylinderOne = new THREE.CylinderGeometry(14, 14, 120, 25, 25, false);
This line is creating the cylinder object. In the above code we have added this line inside the for loop. So it is creating as many number of objects as we want to render on the scene which increases the page load time.

We ca decrease the page load time significantly just by adding creating the object outside the loop, which will create only one object for one geometry and we can reuse the same object as many times to as we want to render on the scene as follows :

var cylinderOne = new THREE.CylinderGeometry(14, 14, 120, 25, 25, false);
for ( var i = 1; i < 6; i ++ ) {
var cylinder = new THREE.Mesh(cylinderOne, new THREE.MeshNormalMaterial());
cylinder.position.x = 10*i;
scene.add(cylinder);
}

Thats it, 🙂 it will increase your page load time…

Advertisements

How to add billing address, shipping address, last 4 digits of CC to global search for Magento backend


Magento backend is having global search functionality,globalSearch
but we can not search few important fields or parameters using global search. 😦
Recently I came across a situation where I need to add many fields to the global search.
After few hours of research, I got the model classes from where it adds the fields to search.

There are three models for customer, product and order, one each.
Path of the files are: 

app/code/core/Mage/Adminhtml/Model/Search/Catalog.php
app/code/core/Mage/Adminhtml/Model/Search/Customer.php
app/code/core/Mage/Adminhtml/Model/Search/Order.php

According to the requirement we can create our custom module in local and overwrite the file(model) over there. From the local we can modify the content of the file to add billing address, shipping address, last 4 digits of CC to global search.

The path of local file:

app/code/local/MyModule/Adminhtml/Model/Search/Catalog.php
app/code/local/MyModule/Adminhtml/Model/Search/Customer.php
app/code/local/MyModule/Adminhtml/Model/Search/Order.php

Note: “MyModule”  is my custom module name in local code pool.
Here I will explain how we can add different address parameters, order id , last 4 digit of CC, customers name etc. For this we will modify Order.php and Customer.php.

Step:1

On this page : app/code/local/MyModule/Adminhtml/Model/Search/Order.php

 $query = $this->getQuery();
        //TODO: add full name logic
        $collection = Mage::getResourceModel('sales/order_collection')
            ->addAttributeToSelect('*')
            ->addAttributeToSearchFilter(array(
                array('attribute' => 'increment_id',       'like'=>$query.'%'),
                array('attribute' => 'billing_firstname',  'like'=>$query.'%'),
                array('attribute' => 'billing_lastname',   'like'=>$query.'%'),
                array('attribute' => 'billing_telephone',  'like'=>$query.'%'),
                array('attribute' => 'billing_postcode',   'like'=>$query.'%'),

                array('attribute' => 'shipping_firstname', 'like'=>$query.'%'),
                array('attribute' => 'shipping_lastname',  'like'=>$query.'%'),
                array('attribute' => 'shipping_telephone', 'like'=>$query.'%'),
                array('attribute' => 'shipping_postcode',  'like'=>$query.'%'),
            ))
            ->setCurPage($this->getStart())
            ->setPageSize($this->getLimit())
            ->load();

We need to change this snippet of code with following snippet to add order increment_id, billing details, shipping details and last 4 digits of CC.

$query = $this->getQuery();
$salesFlatQuotePayment = (string)Mage::getConfig()->getTablePrefix() . 'sales_flat_quote_payment';
            $collection = Mage::getResourceModel('sales/order_collection')->addAttributeToSelect('*');
            $collection->getSelect()
                       ->joinLeft(array('sales_flat_quote_payment' => $salesFlatQuotePayment),
                       "(sales_flat_quote_payment.quote_id=main_table.quote_id)",array('cc_last4')
            ) ;
            
              $collection= $collection->addAttributeToSearchFilter(array(
                    array('attribute' => 'increment_id',                           'like'=>$query.'%'),
                    array('attribute' => 'entity_id',                              'like'=>$query.'%'),
                    array('attribute' => 'billing_firstname',                      'like'=>$query.'%'),
                    array('attribute' => 'billing_lastname',                       'like'=>$query.'%'),
                    array('attribute' => 'billing_telephone',                      'like'=>$query.'%'),
                    array('attribute' => 'billing_postcode',                       'like'=>$query.'%'),
                    array('attribute' => 'billing_o_a.city',                       'like'=>$query.'%'),
                    array('attribute' => 'billing_o_a.region',                     'like'=>$query.'%'),
                    array('attribute' => 'billing_o_a.street',                     'like'=>$query.'%'),
                    array('attribute' => 'sales_flat_quote_payment.cc_last4',      'like'=>'%'.$query.'%'),

                    array('attribute' => 'shipping_firstname',                     'like'=>$query.'%'),
                    array('attribute' => 'shipping_lastname',                      'like'=>$query.'%'),
                    array('attribute' => 'shipping_telephone',                     'like'=>$query.'%'),
                    array('attribute' => 'shipping_postcode',                      'like'=>$query.'%'),
                    array('attribute' => 'shipping_o_a.city',                      'like'=>$query.'%'),
                    array('attribute' => 'shipping_o_a.region',                    'like'=>$query.'%'),
                    array('attribute' => 'shipping_o_a.street',                    'like'=>$query.'%'),
                ))
                ->setCurPage($this->getStart())
                ->setPageSize($this->getLimit())
                ->load();

By adding this code we will be able to search by order increment_id, billing details, shipping details and last 4 digits of CC.

Step:2

On this page : app/code/local/MyModule/Adminhtml/Model/Search/Customer.php

$collection = Mage::getResourceModel('customer/customer_collection')
            ->addNameToSelect()
            ->joinAttribute('company', 'customer_address/company', 'default_billing', null, 'left')
            ->addAttributeToFilter(array(
                array('attribute'=>'firstname', 'like' => $this->getQuery().'%'),
                array('attribute'=>'lastname', 'like'  => $this->getQuery().'%'),
                array('attribute'=>'company', 'like'   => $this->getQuery().'%'),
            ))
            ->setPage(1, 10)
            ->load();

We need to change this snippet of code with following snippet to add default billing address, customer’s  city, region and street.

$collection = Mage::getResourceModel('customer/customer_collection')
                ->addNameToSelect()
                ->joinAttribute('company', 'customer_address/company', 'default_billing', null, 'left')
                ->joinAttribute('city', 'customer_address/city', 'default_billing', null, 'left')
                ->joinAttribute('region', 'customer_address/region', 'default_billing', null, 'left')
                ->joinAttribute('street', 'customer_address/street', 'default_billing', null, 'left')

                ->addAttributeToFilter(array(
                    array('attribute'=>'firstname', 'like' => $query.'%'),
                    array('attribute'=>'lastname', 'like'  => $query.'%'),
                    array('attribute'=>'company', 'like'   => $query.'%'),
                    array('attribute'=>'city', 'like'      => $query.'%'),
                    array('attribute'=>'region', 'like'    => $query.'%'),
                    array('attribute'=>'street', 'like'    => $query.'%'),
                ))
                ->setPage(1, 10)
                ->load();

Now we can upload these two files and flush the cache. Then from backend search for any field from Global Search… 🙂

 

Creating STATIC BLOCK in Magento


Magento Planet

Introduction:
Static block can be used throughout your theme wherever you want to make small updates to a section of a page. Typically uses would be for promotional banners/call-outs in sidebars or for some custom text in the middle of your home page. Static blocks can also be inserted into CMS pages or included in category pages.

Create a Static Block:

Create a Static Block Create a Static Block

View original post 568 more words

Introduction to EAV Model in Magento


Magento Planet

What is EAV Model?
EAV stands for Entity attribute and value model. Let’s closely have a look at all parts.
Entity: In Magento the data items are represented as entity, it can be a product or customer or a category. In the database each entity have a record.
Attribute: These are belongs to different entity, for example a Customer entity have attributes like Name, Age, Address etc. In Magento all attributes are listed in a single table.
Value: Simply the values of the attributes, for example for the Name attribute the value will be “Ram”.

EAV is also known as object–attribute–value model, vertical database model and open schema.

View original post 885 more words

Adding Custom Attribute to the Customer in Magento System


Magento Planet

Introduction:
Sometimes we need some additional attributes for customers. Like products there is no option in the Magento back-end to add custom attribute for Customer. In this blog I will explain step by step how we can create a custom attribute for a customer. As well as how to store, retrieve data for the attribute. We will start from the basic step. First we will create a new module.

Step 1: Module Declaration:
Create a xml file inside app/etc/modules/MFS_Customerattribute.xml

MFS is my name-space name and Customerattribute is my module name. You need to give your name-space name instead of MFS and your module name instead of Customerattribute.
Code:

View original post 284 more words

Wrap different images on different faces of a cube


cubeWe can render different geometry in 3D using three.js.
Here I will explain how we can wrap different image on different faces of a Cube using three.js(revision 68).

Step:1
Here we will Create the cube and wrap a single image on all faces.

 

// Creating the Cube
 var geometry = new THREE.BoxGeometry(2.5,2,2);
 // Adding the image as material to wrap
 var material = new THREE.MeshBasicMaterial( {
 map: THREE.ImageUtils.loadTexture( 'media/image.gif' ) } );
 // Finally Creating the Cube Mesh, wrapping image on its surface
 var cube = new THREE.Mesh(geometry, material);

Step:2
Now lets see how we can modify the code to wrap different images on different faces.

// Creating the Cube
 var geometry = new THREE.BoxGeometry(2.5,2,2);
//Add images to the material array to wrap different image on different faces
 var materialArray = [];
 materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageOne.jpg' ) }));
 materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageTwo.jpg' ) }));
 materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageThree.jpg' ) }));
 materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageFour.jpg' ) }));
 materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageFive.jpg' ) }));
 materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageSix.jpg' ) }));
 var material = new THREE.MeshFaceMaterial(materialArray);
// Finally Creating the Cube Mesh, wrapping image on its surface
 var cube = new THREE.Mesh(geometry, material);

Step:3
Here we will write the complete code to add the Cube to the Scene.

<html>
    <head>
        <title>Image wrap on Cube</title>
        <style>canvas { width: 100%; height: 100% }</style>
    </head>
    <body>
        <!--Adding the three.js library-->
        <script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script>
        <script>
            var scene = new THREE.Scene();
            var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
           
            var renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);
           
            // Creating the Cube, we can change the parameters passed to modify the size of cube :)
            var geometry = new THREE.BoxGeometry(2.5,2,2);
            
            // Add six images to the material array to wrap different image on different faces     
            var materialArray = [];
            materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageOne.jpg' ) }));
            materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageTwo.jpg' ) }));
            materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageThree.jpg' ) }));
            materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageFour.jpg' ) }));
            materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageFive.jpg' ) }));
            materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'media/imageSix.jpg' ) }));
            var material = new THREE.MeshFaceMaterial(materialArray);
            
            // Finally Creating the Cube Mesh, wrapping images on its surface
            var cube = new THREE.Mesh(geometry, material);
            // Adding the cube to scene
            scene.add(cube);
           
            camera.position.z = 5;
           
            var render = function () {
                //Adding rotation to the cube
                requestAnimationFrame(render);
                cube.rotation.x += 0.02;
                cube.rotation.y += 0.02;
                renderer.render(scene, camera);
            };
           
            render();
        </script>
    </body>
</html>

 

Now you can browse it and see a Rotating cube with Images wrapped on its faces 🙂

Reference : http://threejs.org/